What would you do...
Timon Gehr
timon.gehr at gmx.ch
Thu Dec 8 11:43:33 PST 2011
On 12/08/2011 05:23 PM, Manu wrote:
> On 8 December 2011 17:51, Manu <turkeyman at gmail.com
> <mailto:turkeyman at gmail.com>> wrote:
>
> On 8 December 2011 16:27, Jens Mueller <jens.k.mueller at gmx.de
> <mailto:jens.k.mueller at gmx.de>> wrote:
>
> Manu wrote:
> > On 8 December 2011 00:20, Manu <turkeyman at gmail.com
> <mailto:turkeyman at gmail.com>> wrote:
> >
> > > Hey peoples,
> > >
> > > So this might be a bit off topic... but I'm trying to think
> about the best
> > > way to write a small program in the most D-ish way possible
> (just to make
> > > sure I'm giving myself the most realistic experience with
> the language),
> > > and I wanted to get some thoughts.
> > > I don't know which way to go on this. I know what I'd do in
> various other
> > > languages, but I'm curious to hear the communities opinion.
> I think part of
> > > the problem is that D's networking libraries are pretty
> incomplete... but
> > > here it is anyway.
> > >
> > > I basically just want to write a trivial echo server which
> may have
> > > hundreds of thousands of connections split into small
> groups, and whenever
> > > data is received from a member in any group, it is
> basically echoed to the
> > > others in that group.
> > > Sounds super simple...
> > >
> > > My instinct is to have a listener on the main thread, and
> spawn a thread
> > > per group, each blocking on a select().. I think the
> questions is around
> > > thread safety and group management (managing the connection
> list for each
> > > group), and how to interrupt a blocking select() when a new
> connection has
> > > entered the group...
> > > "The D way" to solve these questions is a mystery to me. I
> just feel like
> > > I'm writing C code, manually managing thread safety,
> timeout logic. I feel
> > > like D offers some fundamental features that should make
> solving this
> > > problem a whole lot simpler that I must be completely
> missing...
> > >
> > > So, in a few sentences... simple problem, what would you do?
> > >
> >
> > Nobody at all? :(
> >
> > Quite seriously. I'm trying to work out how D's
> threading/thread safety
> > architecture can help me here.. Also since there's no
> collections, I'm
> > using the associative arrays. How do I manage thread safety
> when accessing
> > those? Is there a generic lock mechanism that I've missed
> along the way
> > without manually creating semaphores? Networking does seem to
> be pretty
> > bare, I'm basically writing C sockets code.
> > One of the results of my experiment here is to identify some
> critical
> > things that appear to be missing from the language. Places
> libraries should
> > really step in and make the task simple. This is a super
> simple network
> > app, but so far, it's just as complicated as if it were
> written in C.
>
> I'm probably wrong or not getting it.
> But to me it seems you have two different things:
> First threads and second connections. For the first I would give
> std.concurrency a try (message passing between the threads). And
> managing a set of connections within a thread is plain C. So using
> select as you do is probably good. If you need to adjust the
> select call
> from time to time you should not let select block indefinitely.
> Use a
> timeout. Another option is pselect which has a signal mask. I
> suppose
> this can also be used to signal abort.
>
> Jens
>
>
> This is basically exactly what I have (although I'm using
> core.thread, I'll swap it for std.concurrency, it does look nicer).
> But it just feels... lame/./
> I'm not sure why though, I can't quite put my finger on it. Maybe
> something irks me about using select() this way, it feels, 1980s :P
>
> The std.concurrency documentation is pretty bad.
> So is std.concurrency.spawn() just effectively a helper for spawning
> a thread that has mailbox support?
> std.concurrency.receive() has no documentation ;) ..
> Blocking/Non-blocking? Should I use the one with duration==0 to do a
> poll? Perhaps there should be an explicit poll() method?
> What is prioritySend()? (also undocumented)
>
>
> Just digging through concurrence.d since the docs are pretty bare, and
> I've come across this pattern, which raises a pretty worrying alarm to
> me. I wonder if this is common in D libraries...
>
>
> void receive(T...)( T ops )
>
> {
>
> checkops( ops );
>
> mbox.get( ops );
>
> }
>
>
> bool receiveTimeout(T...)( Duration duration, T ops )
>
> {
>
> checkops( ops );
>
> return mbox.get( duration, ops );
>
> }
>
>
> Okay, so one calls mbox.get with a duration, makes sense... there must
> be an overload...
>
> finalboolget(T...)(Tvals)
>
> {
> static assert( T.length );
>
> static if( isImplicitlyConvertible!(T[0], Duration) )
>
> {
> alias TypeTuple!(T[1 .. $]) Ops;
>
> alias vals[1 .. $] ops;
>
> assert( vals[0] >= dur!"msecs"(0) );
>
> enum timedWait = true;
>
> Duration period = vals[0];
>
> }
> else
> {
> ... blah blah
>
>
> No overload, receives a tuple, and assumes that static-if the first
> tuple item is IMPLICITLY CONVERTIBLE to a Duration, I must be calling
> the 'overload'...
>
> I guess this means I can never pass a Duration in a message to the
> non-timeout receive()... or anything that is implicitly convertible to a
> Duration.
Sure, receive cannot be called with duration. You pass callbacks to it,
not Durations. Callbacks are never implicitly convertible to Durations,
so that is fine.
> This would seem to be a very obscure hidden bug to me. Is this a common
> pattern in D?
I don't see a 'pattern'.
> I certainly wouldn't want to be tracking down this bug on build
> night... Is there something I've missed here? Some sort of safeguard
> I've overlooked?
Have a look at the checkops template. It catches your case.
I just saw it contains another bug though:
static assert( is( t1 == function ) || is( t1 == delegate ) );
Obviously, the writer meant to check for function pointers and
delegates. This is not what it does. Borken. I think the language should
be fixed here.
More information about the Digitalmars-d
mailing list