/// <summary> /// Shutdown everything from this node down /// </summary> public Unit Shutdown(bool maintainState) { lock (sync) { if (maintainState == false) { cluster.IfSome(c => { // TODO: Make this transactional // { c.Delete(StateKey); c.Delete(ActorInboxCommon.ClusterUserInboxKey(Id)); c.Delete(ActorInboxCommon.ClusterSystemInboxKey(Id)); c.Delete(ActorInboxCommon.ClusterMetaDataKey(Id)); ActorContext.DeregisterById(Id); // } }); } RemoveAllSubscriptions(); publishSubject.OnCompleted(); stateSubject.OnCompleted(); remoteSubsAcquired = false; strategyState = StrategyState.Empty; DisposeState(); ActorContext.DispatchTerminate(Id); return(unit); } }
void ValidateMessageType(object message, ProcessId sender) { if (message == null) { throw new ProcessException($"Invalid message. Null is not allowed for Process ({ProcessId}).", ProcessId.Path, sender.Path, null); } if (message is TerminatedMessage || message is UserControlMessage || message is SystemMessage) { return; } if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { Try <bool> valid = () => { var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); return(meta == null || meta.MsgTypeNames == null ? true : meta.MsgTypeNames.Fold(false, (value, typ) => { var lhsType = Type.GetType(typ)?.GetTypeInfo(); var rhsType = message.GetType().GetTypeInfo(); return value ? true : lhsType.IsAssignableFrom(rhsType); })); }; if (!valid.IfFail(true)) { throw new ProcessException($"Invalid message-type ({message.GetType().Name}) for Process ({ProcessId}).", ProcessId.Path, sender.Path, null); } } }
public Unit Startup(IActor process, ActorItem parent, Option <ICluster> cluster, int maxMailboxSize) { if (cluster.IsNone) { throw new Exception("Remote inboxes not supported when there's no cluster"); } this.tokenSource = new CancellationTokenSource(); this.actor = (Actor <S, T>)process; this.cluster = cluster.LiftUnsafe(); this.maxMailboxSize = maxMailboxSize; this.parent = parent; userNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ActorInboxCommon.ClusterUserInboxKey(actor.Id), true)); sysNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ActorInboxCommon.ClusterSystemInboxKey(actor.Id), false)); SubscribeToSysInboxChannel(); SubscribeToUserInboxChannel(); this.cluster.SetValue(ActorInboxCommon.ClusterMetaDataKey(actor.Id), new ProcessMetaData( new[] { typeof(T).AssemblyQualifiedName }, typeof(S).AssemblyQualifiedName, typeof(S).GetTypeInfo().ImplementedInterfaces.Map(x => x.AssemblyQualifiedName).ToArray() )); return(unit); }
public bool CanAccept <T>() { Try <bool> valid = () => { if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { if (typeof(T) == typeof(TerminatedMessage) || typeof(T) == typeof(UserControlMessage) || typeof(T) == typeof(SystemMessage)) { return(true); } var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); return(meta == null || meta.MsgTypeNames == null ? true : meta.MsgTypeNames.Fold(false, (value, typ) => { var lhsType = Type.GetType(typ)?.GetTypeInfo(); var rhsType = typeof(T).GetTypeInfo(); return value ? true : lhsType.IsAssignableFrom(rhsType); })); } else { return(true); } }; return(valid.IfFail(true)); }
public Unit Startup(IActor process, ActorItem parent, Option <ICluster> cluster, int maxMailboxSize) { if (cluster.IsNone) { throw new Exception("Remote inboxes not supported when there's no cluster"); } this.tokenSource = new CancellationTokenSource(); this.actor = (Actor <S, T>)process; this.cluster = cluster.LiftUnsafe(); this.maxMailboxSize = maxMailboxSize < 0 ? ActorConfig.Default.MaxMailboxSize : maxMailboxSize; this.parent = parent; actorPath = actor.Id.ToString(); userNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ClusterUserInboxKey, true)); sysNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ClusterSystemInboxKey, false)); SubscribeToSysInboxChannel(); SubscribeToUserInboxChannel(); this.cluster.SetValue(ActorInboxCommon.ClusterMetaDataKey(actor.Id), new ProcessMetaData( new[] { typeof(T).FullName }, typeof(S).FullName )); return(unit); }
public Either <string, bool> CanAccept <T>() { if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); return(meta == null ? true : TypeHelper.IsMessageValidForProcess(typeof(T), meta.MsgTypeNames).Map(_ => true)); } else { return(true); } }
void ValidateMessageType(object message, ProcessId sender) { if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); if (meta == null) { return; } TypeHelper.IsMessageValidForProcess(message, meta.MsgTypeNames).IfLeft((string err) => { throw new ProcessException($"{err} for Process ({ProcessId}).", ProcessId.Path, sender.Path, null); }); } }
public Either <string, bool> HasStateTypeOf <T>() { if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); if (meta == null) { return(true); } return(TypeHelper.HasStateTypeOf(typeof(T), meta.StateTypeInterfaces)); } else { return(true); } }
/// <summary> /// Shutdown everything from this node down /// </summary> public Unit Shutdown(bool maintainState) { lock (sync) { if (maintainState == false && Flags != ProcessFlags.Default) { cluster.IfSome(c => { // TODO: Make this transactional // { c.DeleteMany( StateKey, ActorInboxCommon.ClusterUserInboxKey(Id), ActorInboxCommon.ClusterSystemInboxKey(Id), ActorInboxCommon.ClusterMetaDataKey(Id), ActorInboxCommon.ClusterSettingsKey(Id)); ActorContext.DeregisterById(Id); // } ProcessConfig.Settings.ClearInMemorySettingsOverride(ActorInboxCommon.ClusterSettingsKey(Id)); }); } RemoveAllSubscriptions(); publishSubject.OnCompleted(); stateSubject.OnCompleted(); remoteSubsAcquired = false; strategyState = StrategyState.Empty; DisposeState(); ActorContext.DispatchTerminate(Id); return(unit); } }
public bool HasStateTypeOf <T>() { Try <bool> valid = () => { if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId))) { var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId)); var rhsType = meta == null ? null : Type.GetType(meta.StateTypeName)?.GetTypeInfo(); return(meta == null || rhsType == null ? true : typeof(T).GetTypeInfo().IsAssignableFrom(rhsType)); } else { return(true); } }; return(valid.IfFail(true)); }