Skip to content

Instantly share code, notes, and snippets.

@JesseKPhillips
Last active September 24, 2015 16:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JesseKPhillips/773979 to your computer and use it in GitHub Desktop.
Save JesseKPhillips/773979 to your computer and use it in GitHub Desktop.
A translation of some code written in Go to demonstrate Goroutines.
/*
* Original Go: http://www.mprescient.com/journal/2011/1/9/concurrency-in-go-a-call-center-tutorial.html
*/
module main;
import core.thread,
std.array,
std.concurrency,
std.conv,
std.datetime,
std.format,
std.getopt,
std.random,
std.stdio,
std.variant;
struct Call {
int id;
Duration duration;
SysTime start_time;
this(int i, Duration dur, SysTime start) {
id = i;
duration = dur;
start_time = start;
}
}
void callCenter(int agents) {
writeln("Call center opening");
foreach(i; 0..agents) {
auto id = spawn(&agent, i);
id.send(thisTid);
}
Tid[] availableWorker;
Call[] calls;
receive((Tid worker) { availableWorker ~= worker; });
writeln("Call center open");
for(bool running = true; running;) {
receive((Tid worker) { availableWorker ~= worker; },
(Call call) { calls ~= call; },
(OwnerTerminated) { running = false; } );
while(!availableWorker.empty && !calls.empty) {
availableWorker.front.send(calls.front);
availableWorker.popFront();
calls.popFront();
}
}
writeln("Call center closing");
}
void agent(int id) {
writefln("Agent %d logging in\n", id);
auto boss = receiveOnly!Tid();
void handleCall(Call call) {
Thread.sleep(call.duration);
writefln("Agent %s, answering Call %s\n", id, call.id);
writefln("Call %s answered; waited %s\n", call.id, (Clock.currTime() - call.start_time));
}
for(bool running = true; running;) {
boss.send(thisTid);
receive(&handleCall,
(OwnerTerminated) { running = false; } );
}
writefln("Agent %d going home\n", id);
}
void main(string[] args) {
if(args.length < 5) { //if len(args) < 4
writeln("Usage: CallGenerator <numberOfAgents> <numberOfCalls> <maxCallDuration> <maxCallInterval>");
return;
}
int num_agents = to!int(args[1]);
int num_calls = to!int(args[2]);
auto max_dur = hnsecs(to!int(args[3]));
auto max_int = hnsecs(to!int(args[4]));
auto call_center = spawn(&callCenter, num_agents);
setMaxMailboxSize(call_center, 10_000, OnCrowding.throwException);
auto begin = Clock.currTime();
foreach(i; 0..num_calls) {
Thread.sleep(max_int);
call_center.send(Call(i, hnsecs(uniform(1, max_dur.fracSec.hnsecs)), Clock.currTime));
}
auto end = Clock.currTime();
writefln("Simulation elapsed time: %s seconds\n", (end - begin));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment