[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Channel sessions

From: Carl Fredrik Hammar
Subject: Re: Channel sessions
Date: Thu, 02 Aug 2007 16:57:36 +0200
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.1.50 (gnu/linux)


I was writing a reply to your message, trying to sort out this
confusing subject, when it suddenly realized what the source of this

I have considered channels to be a entity corresponding to a
translator, a special translator that cleanly handles character device
semantics.  This worked as long I only considered exclusive access
cases, but when I got to ``multiplexing''. Then I realized that
per-open session data was needed to differentiate clients.

So I started to add session parameters to most channel operations, so
that different clients can get different data (or the same data.)  And
now it seems obvious that each session is a channel in its own right.
And what I called a channel is in-fact the mutable data of the
channel's class.

So in conclusion, a channel is a per-open entity, while a channel
class is a per-server entity.  When you layer channels you actually
layer channel classes, how the actual channels get layered is
class-specific.  The class might open a new channel or it may re-use a
single shared channel.  Actually, ``channel factory'' might be a
better word than class, but I think I'll stick with class.

Hopefully this will clear things up.

<olafBuddenhagen@gmx.net> writes:

> Hi,
> On Thu, Jul 26, 2007 at 09:24:32PM +0200, Carl Fredrik Hammar wrote:
>> My solution is simple enough; they should all be implemented in
>> channels (as opposed to being implemented in channelio.)  This will be
>> more general and give the user more control.  The downside is that it
>> will be a bit more unwieldy, almost every translator will introduce a
>> chain of channels at a time, instead of just one.
> What is the reason for this decision? My feeling is that I should be
> able to individually express every single element of a channel stack
> with a distinct translator...
> Well, maybe I just didn't get your meaning right.

Of course you could still express the stack elements in distinct
translators, but we're dealing with functionality normally provided by
the translator, like buffering.  Introducing a translator that only
differs from its back-end in that it provides buffering doesn't seem
useful, most likely you want it bundled with the lower-most

The unwieldy part is that instead of giving a --buffer or --no-buffer
flag you now have to use channel layering syntax,
e.g. ``buffer:dev:dsp'' (or something like that, I haven't given much
thought to the syntax.)

>> Multiplexors are primarily used to gain multiple sessions to exclusive
>> access devices and also balances io over sub-channels.  E.g. they
>> multiplex in both directions.
> Why do you want to merge these functionalities? They seem totally
> independant -- I can't think of any situation where one would want to
> use both together.
> Maybe there *are* cases where you need multiple inputs and multiple
> outputs in a single component, so it's probably reasonable to leave this
> option open; but I don't think it should be used in any of the standard
> modules.

I agree that they are functionally independent and that performing
both is uncommon.  But they are conceptually similar, they do the same
thing only in different directions.  This way we don't need an `in-tee'
and an `out-tee'.

The good news is that since they are functionally independent, they
don't get in the way of each-other.  Normally you would only layer it
over a single channel, in which case input would simply be forwarded
to the back-end in a fifo manner.

> Also, "multiplexer" is a bad choice of name, as this term is already
> used for a specific kind of translators.

I can't think of anything else to call them collectively.

>> I have identified two generally useful multiplexors.  The simpler one
>> I will just call a `tee'.  It simply forwards each read and write to
>> it's children, to whichever is most responsive or cyclicly if they are
>> equally so.
> [...]
>> More interesting perhaps is a `broadcast' multiplexor, which forwards
>> any input to all it's children and output to all clients in the order
>> received.
> I'm not sure I fully understand your descriptions; but it seems to me
> that what you call "broadcast" is more or less what I was proposing as
> "tee": It takes one input stream and creates several indentical outputs
> from that -- just like the UNIX tool tee. What you call a "tee" on the
> other hand seems to be a simple fifo.

Yes, you've gotten the idea.  I think I'll use your terminology from
now on.  Hopefully fifo won't clash with the UNIX IPC variant,
although I believe it would be possible to implement such a fifo
through libchannel.

> Of course, if merging and splitting are distinct as I suggested above,
> one actually gets four distinct base functionalities, with two variants
> of each of tee and fifo: One multiplexing several devices for a single
> client, and one multiplexing several clients on a single device...

You can get all combinations with the two channel classes I proposed.
By layering a tee over a fifo, each client will have a channel to the
tee, the tee will have a single channel to the fifo, and the fifo will
have one channel per device, or vice-versa.

> This brings up another problem: The fact that for some kinds of
> channels, input and output are rather independant, and may be handled
> differently.
> [...]
> I can think of several approaches for that. One possibility is, if you
> have a module that merges outputs for example, i.e. from all the client
> outputs generates only a single output stream to the device, to simply
> pass through all client inputs as distinct streams (channel instances).
> You could then put another translator below that, which for example
> duplicates all the inputs from a single device stream, and directly
> passes through the output stream.
> Another possibility would be making the input/output split explicit,
> using a dedicated pair of modules for that: First you have a module that
> splits each client session into an output stream and an input stream,
> forwarded to different backends. The output and input backend then could
> be implemented by totally distinct translator paths (sitting on
> different FS nodes). Finally, the other dedicated module would merge
> output and input stream again and forward them to a common device
> backend.
> The above may be the most elegant and transparent solution, but could be
> a bit cumbersome due to the many translators one needs to set
> explicitely. Yet another variant could be using a single special
> translator that internally splits output and input, and passes them to
> two extra modules specified as command line parameters.

Yes this would be the right way to go.  I have already thought about
the whole in/out splitting and reached the same conclusions.

A third would be to have two simplex channels instead of a duplex one,
all the way through.  While it's probably the most generall solution,
it seems to much to cumbersome.

> Seeing the complexity of all this, and considering that you have to
> deliver working code in only a few more weeks, maybe you should just
> leave these issues open for now, and concentrate on the basic
> functionality. But that is something you need to discuss with Richard
> I'd say...
> -antrik-

Yeah, the complexity really does make my head spin. :-)

Luckily I don't need to implement all possible combinations, just make
them possible to implement.  And I think the whole per-open channels
will suffice to make it so.  So I think I'll manage to implement it in


reply via email to

[Prev in Thread] Current Thread [Next in Thread]