dmd-concurrency

Chris Williams yoreanon-chrisw at yahoo.co.jp
Mon Nov 25 13:48:09 PST 2013


On Saturday, 23 November 2013 at 04:18:47 UTC, Shammah Chancellor 
wrote:
> In my uses of channels, I have not found customizing the 
> message box size per channel to be useful.  It may be, but it's 
> not something I want.

I agree that I have not found box size configuration to be a 
significant gain. Being able to configure crowding behavior is 
probably more useful, but there's currently nothing about those 
that would require more than one message box per thread. (And I 
could envision adding a "force in" on-crowding behavior that pops 
from the head and inserts into the tail, but I think I could 
implement that in a reasonable method, even with a shared message 
box.)

> I sitll think duplicate channels should behave the way I 
> described.   Take IRC for example, where I am sending messages 
> to other users, but also to channels which then broadcast.   I 
> want my clients to be able to simply receive() and get messages 
> that were intended for them specifically, or were broadcast.  I 
> don't want to implement complex logic in order to avoid my 
> thread hanging while trying to read from a channel if I have 
> messages available that are specific to my thread.

I'm actually pretty easy on this topic. This was the one reason I 
thought of to try and merge the two systems, but shied away for 
the previously stated reasons.

> With regards to SingleChannel,  picking a random thread would 
> be bad for a plethora of reasons, so I agree here.  I think we 
> should continue to disucss this issue.  There may be some way 
> to get Tid.receive() to behave the expected way when subscribed 
> to SingleChannels.

What I would probably do, by removing receiveAll() and instead 
making receive() grab everything, is expose some methods that 
allow one to either insert directly into a thread's message box 
from a channel or register the channel as something which 
contains its own MessageBox that needs to be checked during a 
receive().

This way, a call to receive() will by default just check the 
thread's MessageBox, and only in special cases attempt to do 
something more extravagant. The overhead for a simple check like 
this is reasonably low that I wouldn't be concerned about adding 
it.

> Also, SingleChannels seem somewhat strange in general to me 
> though -- What is the expected behavior when multiple threads 
> receive different types of mesages from the MessageBox?  Does 
> it consume messages it doesn't understand until it finds one it 
> does?  This would prevent other tasks which do understand them 
> from processing.   What is the use case for SingleChannel that 
> a simple synchronized Queue does not acheive?

I'd say that the main difference between using channels or using 
a synchronized queue are:

1. Developer preference. If you like the actor model, everything 
looks like a nail.

2. Abstraction. My SingleChannel could, for example, be sitting 
on top of something like Amazon's Simple Queue Service (a data 
queue that's maintained on one of their servers, which can have 
items removed by any number of clients). I could set up a thread 
that polls the SQS, pulls an item off, and adds it to a 
synchronized queue, but I might want to write a library that 
translates a request to receive() as a synchronous request, from 
that thread, to the SQS server. With the queue model, the library 
would always have to have its own polling thread. With the 
channel model, either implementation is possible.

3. Multiple entry points. receive() is currently able to directly 
jump to a handler based on the message type. With a queue, I have 
to make everything into a generic Object (or Variant), then 
perform type checks to decide what to do. std.concurrency already 
does all of that, so it's a waste to have to rewrite the same 
sort of handling.

4. Multiple inputs. With the ability to register to multiple data 
sources, using a queue, I have to figure out my own logic for how 
to cycle through my list of sources, so that they're getting 
checked evenly. With the channel system, that is all contained 
for me. I can call register() on 30 different pipes, and not need 
to have to know how the data is being locked, scanned for types I 
support, nor unpackaged for use. It's all just magical, upon 
calling receive().


More information about the Digitalmars-d mailing list