/ k n/shell n/alpha ... / port: ."\\m i ",.i 0 / dependencies: Dir:.i 1 \d D @[.:;"\\l ",.k.Dir,"/dag";:]; \d ^ Dag:+,/(!D){(x;y)}/:'D[] \l /n/dag Nodes:?,/Dag Who[Nodes]:0 / hosts: D:_n \d D @[.:;"\\l ",.k.Dir,"/host";:]; \d ^ Hosts[Nodes]:D Nodes / state: Mu:!0 Out:@[_n;Nodes;:[;()]] Max:0$.i 2 Open:0#` Log[`t`o`n`f`a]:(!0;0#`;0#`;0#`;()) Log..t:"if[0<#*|^Log[];Mu set\\:(`.n.mu.Log;_n;,;(,*|:)'Log[])]" log:{l:_t,,:'x;:[1000>*|^Log[];Log[],:l;Log[]:(1_'Log[]),'l]} / node open: open:{if[(~x _in Open)&~Who x;Open,:x;next[]]} next:{if[(0<#Open)&Max>+/~~Who[];r:queue[];log(`event;;`open;r);Who[r]:0N;spawn[r]Hosts r]} queue:{r:*Open;Open::1_ Open;r} spawn:{if[*(set[y];@[.:;;:])[_n~y]shell x;log(`error;;`open;x);Who[x]:0;open x]} shell:{"\\start \"",($x),"\" /min cmd.exe /c k n/shell n/node",,/" ",'$(_h;_p;x),3_.i} / messages: set:{.[3:;(x;y);:]} get:{.[4:;(x;y);:]} / set: .m.s:{:[Alpha~_n;Alpha::_w;in[who _w]. x]} who:{:[Alpha=x;`alpha;(Nodes[],`)Who[]?x]} in:{:[~`=y;run[x;y]z;x _in Nodes;out[x]z]} run:{y . z;if[x=`alpha;log`alpha,x,y,,z]} out:{log`node,x,y;post[x]node\:y} node:{:[*set[Who x]y;push[x]y;log`out,x,y]} push:{Out[x],:,y;open x} pop:{m:Out x;Out[x]:();x node/:m} / get: .m.g:{:[_n~x;ext[];x _in Nodes;int x;. x]} int:{Who[x]:_w;log(`event;;`connect;x);if[0<#Out x;(_h;_p)3:(`pop;x)];(Dir;ante x)} ext:{Mu,:_w;(Dir;Dag;Log)} / node close: close:{.m.c:"";get[Who x]". .m.c";Who[x]:0;log(`event;;`close;x);.m.c:".k.closed _w";next[]} closed:{:[x _in Mu;Mu::Mu _dv x;x _in Who[];reopen Nodes Who[]?x]} reopen:{Who[x]:0;open x} .m.c:".k.closed _w" / Alpha start/stop: start:{close'Nodes@&0