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