public override async Task IfEffect(StateMachineEvent evt, Command parameter) { var command = (Information)parameter; await _user.UpdateInformation(command); var hubInformation = CreateHubInformation(); await Sender.SendMessage(hubInformation.ToMessage()); }
public override async Task IfEffect(StateMachineEvent evt, Command parameter) { var supportsMessage = new Supports(InformationMessageHeader, new HashSet<string>(Features), null); await Sender.SendMessage(supportsMessage.ToMessage()); var sidMessage = new Sid(new InformationMessageHeader(), User.Sid); await Sender.SendMessage(sidMessage.ToMessage()); }
public void StateMachineEvent(StateMachineEvent stateMachineEvent) { if (onStateMachineEvent != null) { onStateMachineEvent.OnNext(stateMachineEvent); } }
/// <summary> /// Declares a data event on a property of the state machine, and initializes the property /// </summary> /// <param name="propertyExpression">The property</param> /// <param name="eventPropertyExpression">The event property on the property</param> protected virtual void Event <TProperty, T>(Expression <Func <TProperty> > propertyExpression, Expression <Func <TProperty, Event <T> > > eventPropertyExpression) where TProperty : class { PropertyInfo property = propertyExpression.GetPropertyInfo(); var propertyValue = property.GetValue(this, null) as TProperty; if (propertyValue == null) { throw new ArgumentException("The property is not initialized: " + property.Name, nameof(propertyExpression)); } PropertyInfo eventProperty = eventPropertyExpression.GetPropertyInfo(); string name = $"{property.Name}.{eventProperty.Name}"; var @event = new DataEvent <T>(name); if (eventProperty.CanWrite) { eventProperty.SetValue(propertyValue, @event); } else { var objectProperty = propertyValue.GetType().GetProperty(eventProperty.Name, typeof(Event <T>)); if (objectProperty == null || !objectProperty.CanWrite) { throw new ArgumentException($"The event property is not writable: {eventProperty.Name}"); } objectProperty.SetValue(propertyValue, @event); } _eventCache[name] = new StateMachineEvent <TInstance>(@event, false); }
public override async Task<bool> Guard(StateMachineEvent evt, Command parameter) { var command = (Information)parameter; if (!command.Pid.IsDefined) { CreateRequiredFieldIsMissing("PD"); return false; } if (!command.Cid.IsDefined) { CreateRequiredFieldIsMissing("ID"); return false; } var cid = AdcBase32Encoder.Decode(command.Cid.Value); var pid = AdcBase32Encoder.Decode(command.Pid.Value); var hash = new TigerHash().ComputeHash(pid); if (!hash.SequenceEqual(cid)) { CreateInvalidPid(); return false; } if (!command.IpAddressV4.IsDefined && !command.IpAddressV6.IsDefined) { CreateRequiredFieldIsMissing("I4"); return false; } if (command.IpAddressV4.IsDefined && command.IpAddressV4.Value != _user.ClientIPv4.ToString()) { CreateInvalidIPv4(_user.ClientIPv4.ToString()); return false; } if (command.IpAddressV6.IsDefined && command.IpAddressV6.Value != _user.ClientIPv6.ToString()) { CreateInvalidIPv6(_user.ClientIPv6.ToString()); return false; } if (!command.Nickname.IsDefined || string.IsNullOrWhiteSpace(command.Nickname.Value)) { CreateInvalidNick(); return false; } var catalog = ServiceProxy.Create<ICatalog>(new Uri("fabric:/FabricAdcHub.ServiceFabric/Catalog")); if (!await catalog.ReserveNick(_user.Sid, command.Nickname.Value)) { CreateNonUniqueNick(); return false; } return true; }
/// <summary> /// Raise an event of type command /// </summary> /// <param name="eventName"></param> /// <param name="eventInfo"></param> private void RaiseStateMachineSystemCommand( string eventName, string eventInfo) { // Raise event only, if subscriber exist. // Otherwise an exception occurs StateMachineEvent?.Invoke(this, new StateMachineEventArgs( eventName, eventInfo, StateMachineEventType.Command, "State machine")); }
void DeclareDataEvent <T>(PropertyInfo property) { string name = property.Name; var @event = new DataEvent <T>(name); property.SetValue(this, @event); _eventCache[name] = new StateMachineEvent <TInstance>(@event, false); }
public override async Task Effect(StateMachineEvent evt, Command parameter) { if (parameter != null) { var status = new Status(new InformationMessageHeader(), Status.ErrorSeverity.Fatal, Status.ErrorCode.InvalidState, $"Command {parameter.FourCc()} is invalid or not available in PROTOCOL state."); status.OffendingCommandOrMissingFeature.Value = parameter.FourCc(); await Sender.SendMessage(status.ToMessage()); } await User.Close(); }
/// <summary> /// Raises an event of type command /// </summary> /// <param name="eventName"></param> /// <param name="eventInfo"></param> private void RaiseStateMachineSystemCommand(string eventName, string eventInfo) { if (this.StateMachineEvent == null) { return; } StateMachineEvent.Invoke( this, new StateMachineEventArgs(eventName, eventInfo, "State machine", StateMachineEventType.Command)); }
protected void Event <T>(Expression <Func <Event <T> > > propertyExpression) { PropertyInfo property = propertyExpression.GetPropertyInfo(); string name = property.Name; var @event = new DataEvent <T>(name); property.SetValue(this, @event); _eventCache[name] = new StateMachineEvent <TInstance>(@event); }
public bool Inspect <T, V>(DataEvent <T, V> eevent) where T : StateMachine <T> { var target = eevent.CastAs <DataEvent <TStateMachine, V> >(); Func <StateMachineEvent <TStateMachine> > factory = () => new StateMachineEvent <TStateMachine, V>(target, typeof(V)); StateMachineEvent <TStateMachine> sagaEvent = _events.Retrieve(target, factory); sagaEvent.AddState(_currentState); return(true); }
/// <summary> /// Adds a composite event to the state machine. A composite event is triggered when all /// off the required events have been raised. Note that required events cannot be in the initial /// state since it would cause extra instances of the state machine to be created /// </summary> /// <param name="propertyExpression">The composite event</param> /// <param name="trackingPropertyExpression">The property in the instance used to track the state of the composite event</param> /// <param name="events">The events that must be raised before the composite event is raised</param> protected void Event(Expression <Func <Event> > propertyExpression, Expression <Func <TInstance, CompositeEventStatus> > trackingPropertyExpression, params Event[] events) { if (events == null) { throw new ArgumentNullException("events"); } if (events.Length > 31) { throw new ArgumentException("No more than 31 events can be combined into a single event"); } if (events.Length == 0) { throw new ArgumentException("At least one event must be specified for a composite event"); } if (events.Any(x => x == null)) { throw new ArgumentException("One or more events specified has not yet been initialized"); } PropertyInfo eventProperty = propertyExpression.GetPropertyInfo(); PropertyInfo trackingPropertyInfo = trackingPropertyExpression.GetPropertyInfo(); string name = eventProperty.Name; var @event = new SimpleEvent(name); eventProperty.SetValue(this, @event); _eventCache[name] = new StateMachineEvent <TInstance>(@event); var complete = new CompositeEventStatus(Enumerable.Range(0, events.Length) .Aggregate(0, (current, x) => current | (1 << x))); for (int i = 0; i < events.Length; i++) { int flag = 1 << i; var activity = new CompositeEventActivity <TInstance>(trackingPropertyInfo, flag, complete, (consumer, instance) => ((StateMachine <TInstance>) this).RaiseEvent(consumer, instance, @event)); foreach (var state in _stateCache.Where(x => !Equals(x, Initial))) { During(state, When(events[i]) .Then(() => activity)); } } }
public override Task<bool> Guard(StateMachineEvent evt, Command parameter) { var command = (Supports)parameter; for (var index = 0; index != Features.Length; index++) { var feature = Features[index]; if (!command.AddFeatures.Value.Contains(feature)) { CreateRequiredFeatureIsMissing(feature); return Task.FromResult(false); } } return Task.FromResult(true); }
void CompositeEvent(Expression <Func <Event> > propertyExpression, CompositeEventStatusAccessor <TInstance> accessor, CompositeEventOptions options, Event[] events) { if (events == null) { throw new ArgumentNullException(nameof(events)); } if (events.Length > 31) { throw new ArgumentException("No more than 31 events can be combined into a single event"); } if (events.Length == 0) { throw new ArgumentException("At least one event must be specified for a composite event"); } if (events.Any(x => x == null)) { throw new ArgumentException("One or more events specified has not yet been initialized"); } PropertyInfo eventProperty = propertyExpression.GetPropertyInfo(); string name = eventProperty.Name; var @event = new TriggerEvent(name); eventProperty.SetValue(this, @event); _eventCache[name] = new StateMachineEvent <TInstance>(@event, false); var complete = new CompositeEventStatus(Enumerable.Range(0, events.Length) .Aggregate(0, (current, x) => current | (1 << x))); for (int i = 0; i < events.Length; i++) { int flag = 1 << i; var activity = new CompositeEventActivity <TInstance>(accessor, flag, complete, @event); Func <State <TInstance>, bool> filter = x => options.HasFlag(CompositeEventOptions.IncludeInitial) || !Equals(x, Initial); foreach (var state in _stateCache.Values.Where(filter)) { During(state, When(events[i]) .Execute(x => activity)); } } }
public override async Task Effect(StateMachineEvent evt, Command parameter) { if (parameter != null) { var status = new Status(new InformationMessageHeader(), Status.ErrorSeverity.Fatal, Status.ErrorCode.InvalidState, $"Command {parameter.FourCc()} is invalid or not available in IDENTIFY state."); status.OffendingCommandOrMissingFeature.Value = parameter.FourCc(); await Sender.SendMessage(status.ToMessage()); } if (evt.InternalEvent != InternalEvent.DisconnectOccured) { var quit = new Quit(new InformationMessageHeader(), User.Sid); await Sender.SendMessage(quit.ToMessage()); } await User.Close(); }
public override async Task Effect(StateMachineEvent evt, Command parameter) { if (evt.InternalEvent == InternalEvent.ConnectionTimedOut) { // do nothing return; } if (parameter.Type == CommandType.Information) { await User.UpdateInformation((Information)parameter); } else if (parameter.Type == CommandType.Supports) { await User.UpdateInformation((Supports)parameter); } if (parameter.Header is BroadcastMessageHeader) { await BroadcastCommand(parameter); return; } if (parameter.Header is DirectMessageHeader) { await DirectCommand(parameter); return; } if (parameter.Header is EchoMessageHeader) { await EchoedDirectCommand(parameter); return; } if (parameter.Header is FeatureBroadcastMessageHeader) { await FeatureBroadcastCommand(parameter); } }
protected void SendStateMachineEvent(StateMachineEvent @event) { stateMachineEventSubject.OnNext(@event); }
public override Task IfEffect(StateMachineEvent evt, Command parameter) { return Task.CompletedTask; }
public override Task<bool> Guard(StateMachineEvent evt, Command parameter) { var status = (Status)parameter; return Task.FromResult(status.Severity == Status.ErrorSeverity.Fatal); }
public override Task ElseEffect(StateMachineEvent evt, Command parameter) { return Sender.SendMessage(_errorCommand.ToMessage()); }
public override async Task ElseEffect(StateMachineEvent evt, Command parameter) { var quit = new Quit(new InformationMessageHeader(), _user.Sid); await Sender.SendMessage(quit.ToMessage()); await _user.Close(); }
public override async Task Effect(StateMachineEvent evt, Command parameter) { await User.Close(); }
private bool isNotFinished(StateMachineEvent next) => !(next is StateMachineDeadEnd || next is StateMachineError);
private void RaiseStateMachineSystemCommand(string eventName, string eventInfo) => StateMachineEvent?.Invoke(this, new StateMachineEventArgs(eventName, eventInfo, StateMachineEventType.Command, "StateMachine"));