[Coldstuff] $stream

xmath xmath@nubz.org
Sat, 12 Jan 2002 01:46:39 +0100


I've been requested to give some details on the architecture of 
$stream and descendents. First of all, I'm still fiddling with them, 
but they can be viewed by going to:
http://ice.cold.org:1180/bin/object?target=stream
and following the links from there

I also had $local_stream and $local_listener, but I wasn't happy with 
'em yet so I destroyed them. I'll see if I can make 'em again 
tomorrow.

Why $stream?
I basically created it because of a few separate issues I had with 
networking, in genesis and coldcore (UDP is poorly implemented, the 
negative port-number for udp using open_connection is a kludge, and 
in generic there's no room for other protocol, $connection is 
line-oriented without byte-oriented equivalent etc). I designed 
$stream to be a generic and clean system for IO.

What is a $stream?
Basically anything related to IO. The name "stream" doesn't imply 
it's just byte-oriented. It equally well supports streams of 
structures messages. Even the $tcp_listener is a $stream (you could 
say a stream of incoming connections).

Architecture
The internal methods are prefixed with stream_ and are protected. 
They're usually native methods. One major exception is stream_event 
which is actually called by the IO-implementation (usually in 
Genesis) to notify the stream-object of events.
All streams implement some form of stream_open and stream_close 
(arguments may vary). Most streams also implement stream_read and 
stream_write.

Internals
I'd replace both the conn and file fields of Obj by a single stream 
field, a pointer to a structure with a file descriptor and some 
flags. Buffering is done in ColdC rather than Genesis (I doubt this 
will be significantly slower, especially since in Genesis, 
buffer_append is used too). Native methods are placed on whichever 
object is the best place to put them. For example, stream_close is 
placed on $stream because it applies to all streams. If the stream is 
actually fully implemented in ColdC (like local streams or wrapper 
streams) then no harm is done.. they'll just override it 
($stream.stream_close would do nothing or throw an error)

Object overview

$stream: any kind of stream
$data_stream: stream of bytes
$packet_stream: stream of discrete pieces of data (represented by 
single values)
$listener_stream: the name says it all
$tcp_stream, $udp_stream, $tcp_listener, $file_stream should be obvious
$line_stream: a special mix-in to make a stream of bytes into a stream of lines

In all cases, .stream_read and .stream_write are non-buffered and 
non-blocking. The high-level method .read and .write are buffered and 
blocking by default, but this can be overridden with flags.

In case of $tcp_stream, stream_close is not immediate, but instead 
will cause a close-event when the close has been acknowledged. You 
can make it immediate by specifying the 'immediate flag.

The $line_stream object is easy to use: for example, to make a 
line-based TCP stream, make an object with parents: $line_stream, 
$tcp_stream (in that order) and it works.

Note that streams are passive: you just get notified when data has 
arrived, you still have to read it yourself. You could for example 
put a loop in .read_notify that reads lines (non-blocking) and calls 
.parse_line, until no more lines are available.

Well, looks like this is about it. I'm gonna sleep, bye :-)

  - xmath