Port
This implementation of the meta-process allows running external programs and communicating with them using stdin and stdout. Communication can be performed in both text and binary formats.
To create a meta.Port, you need to use the meta.CreatePort function. It takes meta.PortOptions as an argument, which allows specifying the following options:
Cmdcommand to runArgsarguments for the commandEnvenvironment variables for the program being executedEnableEnvMetaadds environment variables of the meta-processEnableEnvOSadds OS environment variablesTagcan help distinguish between multiple meta-processes running with the sameCmd/ArgsProcessThe name of the process that will handlemeta.MessagePort*messages. If not specified, all messages will be sent to the parent process. You can also use anact.Poolprocess for distributing message handlingSplitFuncStdoutto specify a split-function. (usesScannerfrom the standardbufiopackage) for processing data from stdout in text mode. By default, data is split by linesSplitFuncStderrto specify a split-function for the data from stderrBinaryenables binary mode for the data from stdout. See Binary mode for more information
Below is an example of creating and running the external program example-prog using a meta-process meta.Port:
type ActorPort struct {
act.Actor
}
func (ap *ActorPort) Init(args ...any) error {
var options meta.PortOptions
options.Cmd = "example-prog"
// create port
metaport, err := meta.CreatePort(options)
if err != nil {
ap.Log().Error("unable to create Port: %s", err)
return err
}
// spawn meta process
id, err := ap.SpawnMeta(metaport, gen.MetaOptions{})
if err != nil {
ap.Log().Error("unable to spawn port meta-process: %s", err)
return err
}
ap.Log().Info("started Port (iotxt) %s (meta-process: %s)", options.Cmd, id)
return nil
}Binary mode
The implementation of meta.Port supports binary mode when working with stdin/stdout. To enable it, use the meta.PortOptions.Binary.Enable option and specify the binary format parameters:
ReadBufferSizesets the buffer size for reading. The default size is 8192ReadBufferPooldefines a pool for message buffers. TheGetmethod should return an allocated buffer of type[]byteReadChunkenables auto-chunking mode, which splits the incoming stream into chunks according to the specified parameters. For more details, see Auto chunkingWriteBufferKeepAliveenables the software keep-alive mechanism – a specified value will be automatically sent at the interval defined in the optionWriteBufferKeepAlivePeriod
When binary mode is enabled, the SplitFuncStdout option is ignored. However, stderr is processed in text mode, and you can use the SplitFuncStderr option.
Auto chunking
This feature allows automatically chunking the incoming stream in binary mode. The chunks can be of fixed length – to achieve this, you need to specify the chunk size using the FixedLength option. For data with dynamic length, you must specify header parameters that will define the chunk length.
To enable the auto-chunking feature in binary mode, use the meta.PortOptions.Binary.ReadChunk.Enable option, and specify the parameters for automatic data chunking using the following options:
FixedLengthallows you to set the length of chunks in the stdout. In this case, allHeader*options will be ignored. Leave this field with a zero value to work with dynamically sized chunksHeaderSizespecifies the size of the header for dynamically sized chunksHeaderLengthPositionspecifies the position in the header where the length is storedHeaderLengthSizespecifies the size of the length in bytes (1, 2 or 4)HeaderLengthIncludesHeaderspecifies whether the length value includes the header sizeMaxLengthallows you to set the maximum chunk length. If this value is exceeded, the meta-process will terminate, and the launched program will also be automatically stopped. Leave this value as zero if no length limits are required
For instance: incoming stream consists of dynamically sized chunks with a 7-byte header, and the length is encoded as a 32-bit number at the 3rd byte position (counting from 0). The length value includes the header size: L = 7 + len(payload)
__ header _ ___ payload ___
| | | |
x x x L L L L . . . . . . . . .In this case, the auto-chunking options would be as follows
...
var options meta.PortOptions
...
options.Binary.Enable = true
options.Binary.ReadChunk.Enable = true
options.Binary.ReadChunk.HeaderSize = 7
options.Binary.ReadChunk.HeaderLengthPosition = 3
options.Binary.ReadChunk.HeaderLengthSize = 4
options.Binary.ReadChunk.HeaderLengthIncludesHeader = trueYou can find an example implementation in the repository https://github.com/ergo-services/examples, in the port project. Use the -bin argument to enable the demonstration of binary mode operation:

Last updated
Was this helpful?