public Unit ClearData(long time, SessionId sessionId, string key) { Sync.ClearData(sessionId, key, time); cluster.Iter(c => c.Delete(SessionKey(sessionId))); return(cluster.Iter(c => c.PublishToChannel( SessionsNotify, SessionAction.ClearData(time, sessionId, key, system, nodeName)))); }
public int Incoming(SessionAction incoming) { if (incoming.SystemName == system.Value && incoming.NodeName == nodeName.Value) { return(0); } switch (incoming.Tag) { case SessionActionTag.Touch: Touch(incoming.SessionId); break; case SessionActionTag.Start: Start(incoming.SessionId, incoming.Timeout, Map.empty <string, object>()); break; case SessionActionTag.Stop: Stop(incoming.SessionId); break; case SessionActionTag.SetData: var type = Type.GetType(incoming.Type); if (type == null) { logErr("Session-value type not found: " + incoming.Type); } else { var value = Deserialise.Object(incoming.Value, type); if (value == null) { logErr("Session-value is null or failed to deserialise: " + incoming.Value); } else { SetData(incoming.SessionId, incoming.Key, value, incoming.Time); } } break; case SessionActionTag.ClearData: ClearData(incoming.SessionId, incoming.Key, incoming.Time); break; default: return(0); } return(1); }
public Unit SetData(long time, SessionId sessionId, string key, object value) { Sync.SetData(sessionId, key, value, time); cluster.Iter(c => c.HashFieldAddOrUpdate(SessionKey(sessionId), key, value)); return(cluster.Iter(c => c.PublishToChannel(SessionsNotify, SessionAction.SetData( time, sessionId, key, JsonConvert.SerializeObject(value, ActorSystemConfig.Default.JsonSerializerSettings), system, nodeName )))); }
public int Incoming(SessionAction incoming) { if (incoming.SystemName == system.Value && incoming.NodeName == nodeName.Value) return 0; switch(incoming.Tag) { case SessionActionTag.Touch: Touch(incoming.SessionId); break; case SessionActionTag.Start: Start(incoming.SessionId, incoming.Timeout, Map.empty<string,object>()); break; case SessionActionTag.Stop: Stop(incoming.SessionId); break; case SessionActionTag.SetData: var type = Type.GetType(incoming.Type); if (type == null) { logErr("Session-value type not found: " + incoming.Type); } else { var value = Deserialise.Object(incoming.Value, type); if (value == null) { logErr("Session-value is null or failed to deserialise: " + incoming.Value); } else { SetData(incoming.SessionId, incoming.Key, value, incoming.Time); } } break; case SessionActionTag.ClearData: ClearData(incoming.SessionId, incoming.Key, incoming.Time); break; default: return 0; } return 1; }
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 Unit Stop(SessionId sessionId) { Sync.Stop(sessionId); cluster.Iter(c => c.Delete(SessionKey(sessionId))); return(cluster.Iter(c => c.PublishToChannel(SessionsNotify, SessionAction.Stop(sessionId, system, nodeName)))); }
public Unit Start(SessionId sessionId, int timeoutSeconds) { Sync.Start(sessionId, timeoutSeconds, LoadData(sessionId)); cluster.Iter(c => c.HashFieldAddOrUpdate(SessionKey(sessionId), TimeoutKey, timeoutSeconds)); return(cluster.Iter(c => c.PublishToChannel(SessionsNotify, SessionAction.Start(sessionId, timeoutSeconds, system, nodeName)))); }