Last active
September 24, 2015 16:07
-
-
Save JesseKPhillips/773979 to your computer and use it in GitHub Desktop.
A translation of some code written in Go to demonstrate Goroutines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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