DUB module: http://code.dlang.org/packages/jin-go
GIT repo: https://github.com/nin-jin/go.d

Function "go" starts coroutines (vibe.d tasks) in thread pool like in Go language:

        unittest
        {
                import core.time;
                import jin.go;

                __gshared static string[] log;

                static void saying( string message )
                {
                        for( int i = 0 ; i < 3 ; ++i ) {
                                sleep( 100.msecs );
                                log ~= message;
                        }
                }

                go!saying( "hello" );
                sleep( 50.msecs );
                saying( "world" );

log.assertEq([ "hello" , "world" , "hello" , "world" , "hello" , "world" ]);
        }

Class "Channel" is wait-free one-consumer-one-provider channel. By default, Channel blocks thread on receive from clear channel or send to full channel:

unittest
{
        static void summing( Channel!int output ) {
                foreach( i ; ( output.size * 2 ).iota ) {
                        output.next = 1;
                }
                output.close();
        }

        auto input = go!summing;
        while( !input.full ) yield;

        input.sum.assertEq( input.size * 2 );
}

You can no wait if you do not want:

        unittest
        {
                import core.time;
                import jin.go;

                static auto after( Channel!bool channel , Duration dur )
                {
                        sleep( dur );
                        if( !channel.closed ) channel.next = true;
                }

                static auto tick( Channel!bool channel , Duration dur )
                {
                        while( !channel.closed ) after( channel , dur );
                }

                auto ticks = go!tick( 101.msecs );
                auto booms = go!after( 501.msecs );

                string log;

                while( booms.clear )
                {
                        while( !ticks.clear ) {
                                log ~= "tick";
                                ticks.popFront;
                        }
                        log ~= ".";
                        sleep( 51.msecs );
                }
                log ~= "BOOM!";

                log.assertEq( "..tick..tick..tick..tick..BOOM!" );
        }

Channel are InputRange and OutputRange compatible. Structs "Inputs" and "Outputs" are round-robin facade to array of channels.

More examples in unit tests: https://github.com/nin-jin/go.d/blob/master/source/jin/go.d#L293

Current problems:

1. You can give channel to more than two thread. I'm going to play with unique pointers to solve this problem. Any hints?

2. Sometimes you must close channel to notify partner to break range cycle. Solving (1) problem can solve and this.

3. API may be better. Advices?

Reply via email to