Description

Thread-pooled coroutines with lock-free staticaly typed communication channels

Package Information

Version1.0.5 (2016-Mar-29)
Repository https://github.com/nin-jin/go.d
Licensepublic domain
Copyrightpublic domain © 2015, jin
Authorsjin
Registered bynin jin
Dependencies

vibe-d:core

dests

Installation

To use this package, put the following dependency into your project's dependencies section:

dub.json
dub.sdl

Readme

Go.d

Thread-pooled coroutines with wait-free staticaly typed communication channels

Build Status Join the chat at https://gitter.im/nin-jin/go.d

Features

  • Static typed channels
  • Lock free channels
  • Minimal message size

ToDo

  • Allow only one input and output ref
  • Autoclose channels

Usage

dub.json:

{
	"dependencies": {
		"jin-go": "~>1.0.0"
	}
}

Import

import jin.go;

Create channels

auto ints = new Channel!int;

struct Data { int val }
struct End {}
alias Algebraic!(Data,End) Message 
auto messages = new Channel!Message;

Inputs!int ints;
auto channel = ints.make;

Outputs!int ints;
auto channel = ints.make;

Start coroutines

void incrementing( Channel!int results , Channel!int inputs ) {
	while( true ) {
		results.next = inputs.next + 1;
	}
}

go!incrementing( results.make , ints.make );
auto results = go!incrementing( ints.make );

void squaring( int limit ) {
	return limit.iota.map( i => i^^2 );
}
auto squares = go!squaring( 10 );

Send messages

waits while outbox/outboxes is full

ints.next = 123; // send message
ints.next!Data = 123; // make and send message
ints.put( 123 ); // OutputRange style

Receive messages

waits for any message in inbox/inboxes

writeln( results.next ); // get one message
writeln( results.next.get!Data ); // get value from one Message

// visit one Message
results.next.visit!(
	( Data data ) { writeln( data ); } ,
	( End end ) { } ,
);

// handle messages in cycle
while( !results.empty ) {
	if( !results.clear ) writeln( results.next );
};

// handle messages from multiple channels in cycle
while( !one.empty || !two.empty ) {
	if( !one.clear ) writeln( one.next );
	if( !two.clear ) writeln( two.next );
}

Complete example

import core.time;
import std.stdio;
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 );
}

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

	string log;

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

More examples in unit tests

Available versions

1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 ~master ~safe-channels ~lock-free