private void FetchServices(Timer obj)
        {
            var knownServices = RemoteServerManager.GetAllGroups().SelectMany(g => g.GetAllRemoteServers()).Select(s => s.ID);
            var joined        = registry.Keys.Except(knownServices);
            var left          = knownServices.Except(registry.Keys);

            foreach (ushort joinedID in joined)
            {
                if (joinedID != RemoteServerManager.ServerID)
                {
                    RegistryEntry service = registry[joinedID];
                    string        group   = service.Group;

                    Logger.Trace($"Discovered server {joinedID} from group '{group}'.");

                    HandleServerJoin(joinedID, group, service.Host, service.Port, new Dictionary <string, string>(service.Properties));
                }
            }

            //TODO consider just a set method instead of/as well as join/leave
            foreach (ushort leftID in left)
            {
                if (leftID != RemoteServerManager.ServerID)
                {
                    Logger.Trace($"Server {leftID} has left the cluster.");

                    HandleServerLeave(leftID);
                }
            }
        }
 public InMemoryServerRegistryConnector(ServerRegistryConnectorLoadData serverRegistryConnectorLoadData) : base(serverRegistryConnectorLoadData)
 {
     timer = CreateTimer(1000, 1000, FetchServices);
 }