Format components apply structural formats to the data stream as it passes through them. For example, format components
may parse a datastream into HTTP requests and responses or format the data stream as JSON or another structured
encoding. Formats may exist in either the input or output chains of the vhs
data flow. Input formats and output
formats must be implemented separately. Information on the input and output formats available in the current release of
vhs
is available here: input formats and output
formats
Internally, the implementation of a format bears some resemblance to that of a source, with the added wrinkle of reading from an incoming channel.
Input formats must conform to the InputFormat
interface as implemented in
core/input_format.go
and shown below:
// InputFormat is an interface for formatting input
type InputFormat interface {
Init(session.Context, middleware.Middleware, <-chan InputReader)
Out() <-chan interface{}
}
An input format must read from a channel of
InputReader
passed to the Init
function and
write formatted output to the Out()
channel.
Output formats must conform to the OutputFormat
interface as implemented in
core/output_format.go
and shown below:
// OutputFormat is an interface for formatting output
type OutputFormat interface {
Init(session.Context, io.Writer)
In() chan<- interface{}
}
The output format interface is essentially the reverse of the input format interface. An output format must read
interface{}
from the In()
channel and write bytes to the io.Writer
passed to the Init
function.
In both the input format and the output format, the Init
function is responsible for the initialization and internal
processing of the format. It will be run in its own goroutine by the vhs
flow infrastructure. It may use internal
goroutines, but all internal goroutines should clean up and exit upon receipt of a signal on core.Context.Done()
.
Since formats read and write concurrently, avoidance of deadlocks and bottlenecks is critical. It may be useful to
employ two goroutines internally, one to read from the incoming channel and one to write to the outgoing location to
avoid contention and blocking.
Other considerations when developing formats are similar to other components:
session.Context
. This constructor may be trivial.newRootCmd
in
cmd/vhs/main.go
. The values of these flags should be
stored in FlowConfig
in the session
package at
core/config.go
. These values will then be
available within your package as part of the core.Context
.vhs
data flow that is not
strongly typed. Developers should consider this when designing formats and provide documentation indicating the
compatibility of their formats with other formats.The json
input and output formats are useful examples of input and
output format implementations. They are found in the jsonx
package at
jsonx/jsonx.go
.
The http
input and output formats present more complex examples of formats, including
handling of middleware on the input format. They are implemented in the httpx
package at
httpx/input_format.go
and
httpx/output_format.go
.