HydraTools and minimal images

Igor Stasenko siguctua at gmail.com
Wed Feb 13 14:49:33 UTC 2008


On 13/02/2008, Klaus D. Witzel <klaus.witzel at cobss.com> wrote:
> Hi Igor,
>
> on Wed, 13 Feb 2008 13:24:05 +0100, you wrote:
>
> > On 13/02/2008, Klaus D. Witzel wrote:
> >> Hi Igor,
> >>
> >> on Wed, 13 Feb 2008 09:35:09 +0100, you wrote:
> >>
> ...
> >> > But before going deep, i would like to get some feedback on channels
> >> > implementation.
> >>
> >> If I had a wish free then I'd say that Hydra's channels could provide
> >> the
> >> [a sensible part of] existing vocabulary of Socket (Socket's messages
> >> categories #open, #queries, #receiving, #sending and #waiting).
> >>
> >
> > There is, a waiting (hidden from your eyes).
> > You can check the HydraReceivingChannel>>startListening: aBlock
> >
> > VM signals a semaphore, when data arrives on channel, so a process
> > which is waiting on that semaphore is then awaken and can do anything
> > he needs to handle incoming packet.
>
> If these you lines are related to my #waitForDataFor:ifClosed:ifTimedOut:
> question (I assume that):
>
> a] the timeout can occur while waiting (listening)
> b] the close can occur while waiting (listening)
> c] data can arrive while waiting
>
> Case c] is easy with the #startListening: but how about capturing the
> other two cases?
>

There is no 'close' action, there is only 'stop listening' action. So,
case b is simply impossible with such design.
Case a] can be simply implemented if you place #waitTimeoutMsecs:
instead of just #wait.
Everything in our hands :)

> > Actually, you can omit using semaphore, and just pull data from
> > channel at any time you need.
>
> It would have to know that there's no data to pull (and why that is so),
> that is what #waitForDataFor:ifClosed:ifTimedOut: is about (besides
> pulling data).
>
> > The readData primitive works pretty straightforward: If there is data
> > waiting on channel, you'll receive a bytearray, if not - you just
> > receive a nil in response, indicating that channel input queue is
> > empty.
> > So, you can implement own listening scheme, which polls channel for
> > data periodically, and if there is no data received after supplied
> > timeout, evaluate a onTimeOut handler..
>
> IC.
>
> >> This would make porting Socket-based applications easier and can
> >> leverage
> >> existing knowledge about Sockets.
> >>
> >> > There is some very interesting alternatives, which should be
> >> considered.
> >> ...
> >> > ---
> >> > Alternatives:
> >> ...
> >> > - adding some feedback mechanism, when incoming packet can't be
> >> > delivered (when channel input queue is full, or simply there is no
> >> > channel with given credentials).
> >>
> >> Considering a port one of my projects which currently is using Sockets,
> >> what I'm missing is something like #waitForDataFor:ifClosed:ifTimedOut:
> >>
> >
> > A channels is unidirectional. You sending data and have no feedback.
> > It works in same way as UDP sockets.
> > But on top of UDP you can always build more sophisticated layers (as
> > bidirectional streams), where you can introduce behavior like
> > #waitForDataFor:ifClosed:ifTimedOut:.
> >
> >> Is something like that possible with the Hydra channels primitives?
> >
> > ... and there is no need to make it at VM level. It can be easily done
> > at language level.
> >
> >>
> >> > I'm not sure, if this is really needed to be implemented by VM. An
> >> > efficient error/feedback mechanisms can be implemented very easily at
> >> > language side.
> >>
> >> It wouldn't need more/other error/feedback than what Socket provides
> >> today, IMHO.
> >>
> >> BTW: what's happening now if the second .image does no longer respond to
> >> the first .image, how can/does the other .image get known to this?
> >
> > Again, there is no 'response' in any means.
>
> So I have to teach the app's users, "there's no response" ;-)

Well, i assume there is developer standing between low-level APIs and
application, who makes everything he needs to eliminate the need in
teaching users about anything :)

I would like to hear, is there enough functionality in channel
_primitives_ (not classes which currently using them), which would
allow you to build more sophisticated communication frameworks.
As far, as i can see, from cases you given, there is no need to
add/change anything to VM's primitives.

>
> > Channels just listening
> > for data. You can send data to channel, but you don't getting any
> > feedback about if it was delivered or handled.
>
> More seriously, I understand that in order to save the whole app from
> potentially "freezing on no response", some timeout mechanism needs to be
> added. But timeout alone cannot find out that the other .image has gone
> away. Is there something you would suggest for checking the other .image
> is still alive (or not alive)?
>
> NB: this check is independent of using Sockets or Hydra channels between
> any pair of Hydra .images, but it looks like there can be easier control
> with Hydra because everything is on the same machine.
>

You can check:
- if there is still an interpreter in VM (
HydraVM>>#isValidInterpreterInstance:)
- if there is still a channel, listening at given interpreter
instance. You may check, it by using discover primitive, and check the
newly received id and magic and compare them with previously received.

A channel is identified by a pair: interpreter handle and name
(by analogy as IP address and port number)

A HydraSendingChannel using
#primitiveDiscoverChannelIn: intr name: aname
to get channel's id and magic numbers.

Once id and magic are received, it can use them in
primitiveSendDataTo: intr channelId: anId magicNum: aMagic data: aData
to send data to channel.

If that primitive fails, it means, that given interpreter handle is
not valid anymore.
Or, aData object is not a bytearray.
Note: at this stage it's not checking that given channel exists!
So, if you continue sending data to channel with bad id/magic but
valid interpreter handle, it will be silently accepted. This is the
price we pay in having multiple interpreters running in parallel.

I'm using id/magic instead of just name to not search and compare
strings in channel list every time you sending data. This is done
simply for speed reasons.
Also, magic number is unique for all channels instances in image. This
means, that if you stop listening existing channel, and then start
listening new even with same name, it will receive different magic
number, which will prevent it from receiving any packets addressed to
previous one.

Yes, any senders that was targeted to send data to closed channel are
not notified automatically upon channel close.
But look at bright side: nothing stops you from implementing such
notification :)

One could create a #control channel (which will be a part of his
reliable communication framework), and ControlledHydraChannel , which
upon closing will broadcast to all current interpreters #control
channels that it's closing, so they can make  appropriate actions by
receiving such event.

I think, there can be many ways, how you can build communication
framework using channels. Some people would like it to behave same as
IP stream sockets, some are not.

> > To build a system with feedback all you need is to setup two channels
> > (one for each image) and create a feedback protocol, like, when
> > channel receives a message, it sends a message back, that he is
> > actually received it :)
>
> Sure, DIY :)
>
> > As a small exercise of bidirectional communication, you can check
> > HydraPing class.
>
> Sure.
>
> >> /Klaus
> >>
> >>

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list