protected override void OnReceive(object message)
{
var createServerFSM = message as CreateServerFSM;
if (createServerFSM != null)
{
var channel = createServerFSM.Channel;
var host = (IPEndPoint)channel.RemoteAddress;
var name = WebUtility.UrlEncode(host + ":" + host.Port + "-server" + _generation++);
var fsm = Context.ActorOf(
Props.Create(() => new ServerFSM(Self, channel)).WithDeploy(Deploy.Local), name);
_log.Debug("Sending FSM {0} to {1}", fsm, Sender);
Sender.Tell(fsm);
return;
}
var nodeInfo = message as NodeInfo;
if (nodeInfo != null)
{
_barrier.Forward(nodeInfo);
if (_nodes.ContainsKey(nodeInfo.Name))
{
if (_initialParticipants > 0)
{
foreach (var ni in _nodes.Values)
ni.FSM.Tell(new ToClient<BarrierResult>(new BarrierResult("initial startup", false)));
_initialParticipants = 0;
}
nodeInfo.FSM.Tell(new ToClient<BarrierResult>(new BarrierResult("initial startup", false)));
}
else
{
_nodes = _nodes.Add(nodeInfo.Name, nodeInfo);
if(_initialParticipants <= 0) nodeInfo.FSM.Tell(new ToClient<Done>(Done.Instance));
else if (_nodes.Count == _initialParticipants)
{
foreach (var ni in _nodes.Values) ni.FSM.Tell(new ToClient<Done>(Done.Instance));
_initialParticipants = 0;
}
if (_addrInterest.ContainsKey(nodeInfo.Name))
{
foreach(var a in _addrInterest[nodeInfo.Name]) a.Tell(new ToClient<AddressReply>(new AddressReply(nodeInfo.Name, nodeInfo.Addr)));
_addrInterest = _addrInterest.Remove(nodeInfo.Name);
}
}
}
var clientDisconnected = message as ClientDisconnected;
if (clientDisconnected != null && clientDisconnected.Name != null)
{
_nodes = _nodes.Remove(clientDisconnected.Name);
_barrier.Forward(clientDisconnected);
return;
}
if (message is IServerOp)
{
if (message is EnterBarrier)
{
_barrier.Forward(message);
return;
}
if (message is FailBarrier)
{
_barrier.Forward(message);
return;
}
var getAddress = message as GetAddress;
if (getAddress != null)
{
var node = getAddress.Node;
if (_nodes.ContainsKey(node))
Sender.Tell(new ToClient<AddressReply>(new AddressReply(node, _nodes[node].Addr)));
else
{
ImmutableHashSet<IActorRef> existing;
_addrInterest = _addrInterest.SetItem(node,
(_addrInterest.TryGetValue(node, out existing)
? existing
: ImmutableHashSet.Create<IActorRef>()
).Add(Sender));
}
return;
}
if (message is Done) return; //FIXME what should happen?
}
if (message is ICommandOp)
{
var throttle = message as Throttle;
if (throttle != null)
{
var t = _nodes[throttle.Target];
_nodes[throttle.Node].FSM.Forward(new ToClient<ThrottleMsg>(new ThrottleMsg(t.Addr, throttle.Direction, throttle.RateMBit)));
return;
}
var disconnect = message as Disconnect;
if (disconnect != null)
{
var t = _nodes[disconnect.Target];
_nodes[disconnect.Node].FSM.Forward((new ToClient<DisconnectMsg>(new DisconnectMsg(t.Addr, disconnect.Abort))));
return;
}
var terminate = message as Terminate;
if (terminate != null)
{
_barrier.Tell(new BarrierCoordinator.RemoveClient(terminate.Node));
_nodes[terminate.Node].FSM.Forward(new ToClient<TerminateMsg>(new TerminateMsg(terminate.ShutdownOrExit)));
_nodes = _nodes.Remove(terminate.Node);
return;
}
var remove = message as Remove;
if (remove != null)
{
_barrier.Tell(new BarrierCoordinator.RemoveClient(remove.Node));
return;
}
}
if (message is GetNodes)
{
Sender.Tell(_nodes.Keys);
return;
}
if (message is GetSockAddr)
{
Sender.Tell(_connection.LocalAddress);
return;
}
}