What would you do...

Manu turkeyman at gmail.com
Thu Dec 8 08:23:55 PST 2011


On 8 December 2011 17:51, Manu <turkeyman at gmail.com> wrote:

> On 8 December 2011 16:27, Jens Mueller <jens.k.mueller at gmx.de> wrote:
>
>> Manu wrote:
>> > On 8 December 2011 00:20, Manu <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...


        final bool get(T...)( T vals )
        {
            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.
This would seem to be a very obscure hidden bug to me. Is this a common
pattern in D?
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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20111208/6662ee96/attachment-0001.html>


More information about the Digitalmars-d mailing list