public SessionManager(Option<ICluster> cluster, SystemName system, ProcessName nodeName, VectorConflictStrategy strategy) { this.cluster = cluster; this.system = system; this.nodeName = nodeName; Sync = new SessionSync(system, nodeName, strategy); cluster.Iter(c => { notify = c.SubscribeToChannel<SessionAction>(SessionsNotify).Subscribe(act => Sync.Incoming(act)); var now = DateTime.UtcNow; // Look for stranded sessions that haven't been removed properly. This is done once only // on startup because the systems should be shutting down sessions on their own. This just // catches the situation where an app-domain died without shutting down properly. c.QuerySessionKeys() .Map(key => from ts in c.GetHashField<long>(key, LastAccessKey) from to in c.GetHashField<int>(key, TimeoutKey) where new DateTime(ts) < now.AddSeconds(to * 2) // Multiply by 2, just to catch genuine non-active sessions select c.Delete(key)) .Iter(id => { }); // Remove session keys when an in-memory session ends ended = SessionEnded.Subscribe(sid => Stop(sid)); touch = Sync.Touched.Subscribe(tup => { try { c.HashFieldAddOrUpdate(SessionKey(tup.Item1), LastAccessKey, DateTime.UtcNow.Ticks); c.PublishToChannel(SessionsNotify, SessionAction.Touch(tup.Item1, system, nodeName)); } catch(Exception e) { logErr(e); } }); }); }
public SessionManager(Option <ICluster> cluster, SystemName system, ProcessName nodeName, VectorConflictStrategy strategy) { this.cluster = cluster; this.system = system; this.nodeName = nodeName; Sync = new SessionSync(system, nodeName, strategy); cluster.Iter(c => { notify = c.SubscribeToChannel <SessionAction>(SessionsNotify).Subscribe(act => Sync.Incoming(act)); var now = DateTime.UtcNow; // Look for stranded sessions that haven't been removed properly. This is done once only // on startup because the systems should be shutting down sessions on their own. This just // catches the situation where an app-domain died without shutting down properly. c.QuerySessionKeys() .Map(key => from ts in c.GetHashField <long>(key, LastAccessKey) from to in c.GetHashField <int>(key, TimeoutKey) where new DateTime(ts) < now.AddSeconds(to * 2) // Multiply by 2, just to catch genuine non-active sessions select c.Delete(key)) .Iter(id => { }); // Remove session keys when an in-memory session ends ended = SessionEnded.Subscribe(sid => Stop(sid)); touch = Sync.Touched.Subscribe(tup => { try { c.HashFieldAddOrUpdate(SessionKey(tup.Item1), LastAccessKey, DateTime.UtcNow.Ticks); c.PublishToChannel(SessionsNotify, SessionAction.Touch(tup.Item1, system, nodeName)); } catch (Exception e) { logErr(e); } }); }); }
/// <summary> /// Setup /// </summary> /// <param name="sessionManager">Process ID of the session manager</param> /// <param name="checkFreq">Frequency to check</param> public static Tuple<SessionSync, Time> Setup(SessionSync sync, Time checkFreq) => Tuple(sync, checkFreq);
/// <summary> /// Setup /// </summary> /// <param name="sessionManager">Process ID of the session manager</param> /// <param name="checkFreq">Frequency to check</param> public static Tuple <SessionSync, Time> Setup(SessionSync sync, Time checkFreq) => Tuple(sync, checkFreq);