[erlang-questions] Ideas for a new Erlang

Sven-Olof Nystr|m <>
Fri Aug 1 15:24:23 CEST 2008


Ulf Wiger writes:
 > > Ulf Wiger writes:
 > >  > You should also take a look at the presentation that I referred to.

Two general comments on the slides:

 1) I don't think the comparison with the select operation of Unix is
    valid. Even without selecive receive, it is easy enough to set up
    an Erlang process to wait until one out of a number of things
    happen.

 2) One of the problem you are discussing is how to describe
    concurrent activities within one state machine. UML's mechanism
    for expressing composite state seems to be close to what is needed
    here.

 > >  > Just looking at the example in the book, you are making the same
 > >  > mistake as the Nordlander thesis on OHaskell. The POTS system
 > >  > also uses messages to control the switch hardware, and this control
 > >  > is stateful and synchronous. Furthermore, I believe that the MD110
 > >  > hardware had no way to queue requests, so the control system must
 > >  > take care to issue only one request at a time.

OK, I've looked at Nordlander's thesis.

In OHaskell, there are two ways of specifying that an object may
accept communication; keywords "action" and "request". The second is
similar to what in the Erlang world is referred to as synchronous
communication. It seems to me that using "request" you would get the
same behaviour as send/request pairs in Erlang.

  > >  >
 > >  > The OHaskell example assumed that functions like start_tone()
 > >  > were atomic and non-blocking - they are not.

What would go wrong if the implementation of start_tone() and similar
functions was non-blocking?

 > >
 > > OK, I actually wrote a simple framework to be able to run the
 > > code. The framework used a process to simulate the hardware and
 > > naturally there were some receive expressions, for example in
 > > analyse(). But the function start_tone and other similar functions
 > > were not blocking. I saw those as being outside the POTS example, so I
 > > did not comment on them. (The communications followed the simple
 > > pattern I discussed in the example with the counter program.)
 > >
 > >  > In my presentation, I also made the number analysis asynchronous,
 > >  > which may seem far-fetched in the limited POTS example, but is quite
 > >  > realistic when one considers modern IP-based telephone. The
 > >  > idea was to convert synchronous requests into explicit asynchronous
 > >  > request-reply pairs, and having at least two such protocols that could
 > >  > interleave.
 > >
 > > I noted a slide with the comment "simple main event loop with fifo
 > > semantics". Seems to be similar to what I am trying to do.
 > >
 > > You bring up some interesting issues in your presentation but the code
 > > you show don't seem to make much use of selective receive.
 > 
 > Not much, but the vital use of selective receive is in the start_tone()
 > and similar functions. The key part is that the function blocks and
 > waits for a specific response to its particular signal, and doesn't
 > return to the surrounding control loop until it knows whether or
 > not the operation succeeded. Since selective receive makes this
 > possible, the top-level control loop is free to assume that start_tone()
 > is atomic. This particular assumption is illegal in OHaskell, for example.

Making start_tone() synchronous is straight-forward using channels.

 > > I am not sure what you mean by synchronous and unsynchronous. In
 > > an Erlang context, I thought synchronous meant a communication
 > > implemented as a send-request pair, but you seem to be making a
 > > distinction here. Also, aren't all Erlang programs event-based
 > > (event=message)?
 > 
 > No, that's the interpretation of synchronous that I meant.
 > Many programming frameworks do not allow operations
 > like start_tone() to block, which means that such operations
 > must be carried out as explicit request-reply pairs, which
 > become visible in the global state-event matrix.
 > 
 > The last example in the presentation implements a filtering
 > event loop, which might be similar to a solution using
 > channels.

I was wondering about that.

The filtered event loop (page 24) in your presentation makes
assumptions on how states are represented (as tuples of sub-states?)
and what messages look like (containing indexes into the state
tuples?):

event_loop(M, S, Recv) ->
  receive 
    {From, Event} when element(From, Recv) == [] ->
      dispatch(From, Event, M, S);
    {From, Ref, Event} when element(From, Recv) == Ref ->
      dispatch(From, Event, M, S);
    {From, Ref, Event} when element(From, Recv) == [] ->
      dispatch(From, Event, M, S)
end.

Here, one Erlang process implements several concurrent activities.
However, it's unclear how these activities are represented. The
preceeding slides give some hint to what is going on, but not the
whole story.

(From looking at the code, I get the impression that event_loop
actually makes heavy use of selective receive, but whether this is the
case or not depends of course on the context.)


 > >  > A SIP signaling control system can make as much as 5-10 network-
 > >  > based (or more) requests for one call, for things like billing,
 > >  > admission control, location lookup, resource allocation, etc.
 > >  > All conceptually synchronous,  but the SIP signaling is asynchronous.
 > >  > The interleaving of all signals make a global state-event matrix
 > >  > impossibly complicated, so conceptual layering is essential.
 > >
 > > This is interesting stuff. I suppose one can't simply split one side
 > > of a communication into several processes?
 > 
 > Sure, but that doesn't solve the problem.
 > 
 > Take the case of admission control. It is triggered by the main
 > call control state machine, and the continuation depends on
 > the result of the request. It's prudent to let a separate process
 > deal with the DIAMETER specifics (which may involve failure
 > detection and retransmission/rerouting of the request), but
 > the main state machine must still await the result. If it
 > sends the request and doesn't selectively wait for the reply,
 > other signals may arrive that conflict with the outstanding
 > request. 

I'm not sure I get this. Waiting for a reply to a particular request
using channels is straight-forward. I can see that it might be hairy
to break down a side into several processes, but it still seems to be
a viable approach.


 >         If I implement a wrapper around the DIAMETER
 > request-response pair used for admission control, it doesn't affect
 > the state machine any more than if it were an atomic check of a
 > locally stored value.

I agree with the last sentence, but I don't see how this makes it
harder to break down a side into processes. After all, regardless of
how the result is computed, you still need to wait for it.



Sven-Olof







More information about the erlang-questions mailing list