I have a program with several long pipes with several transforms.
e.g.
socket.pipe(ta).pipe(tb).pipe(tc);
...
tc.pipe(other_socket);
What is the best way of adding/reading meta data to/from the pipe?
For example: ta
accumulates and breaks packets into lines. tb
needs to prefix each line with data based on the originating IP address (if any).
How can tb
get the remoteAddress
from its input?
There seem to be some similarities with prototypical inheritance here. i.e. tb
should ask ta
(which lacks the property) then ta
should ask socket
(which has the property).
I'm looking for a general approach to adding and reading metadata from pipes, as I have other more complex, but analogous issues.
I'm currently solving this issue by using 'Object Streams' consisting of objects with meta
and payload
properties. Each transform has to do its stuff to payload
and most leave meta
alone. This solution is ugly, especially as I've had to create a new xnet
module which looks like net
but produces these augmented objects, rather than plain buffers or strings.
(Haskellers might recognise this solution as a Monad, where I'm lifting most of the stream transforms I use into a "meta" Monad. I'm still learning Haskell, so this observation may be incorrect.)
If the meta data is read-only data for particular instance of pipeline execution then why not pass this data while creating the individual pipes. Something like : socket.pipe(new Ta(address))
In terms of Haskell, it sounds like a Reader moand, where the Pipeline execution function takes a Reader which full fill all the meta data requirements of individual pipes of the pipeline