public static string DoesNotExist( GangState <HostState> state, string id) { return(state.Data.Users.Any(u => u.Id == id) ? ERROR_USER_EXIST : null); }
async Task <GangState <TStateData> > RehydrateAsync <TStateData>( string gangId, TStateData initial ) where TStateData : class { var data = initial; var version = 0U; var keys = await _eventStore.TryGetIndexedKeys(gangId); foreach (var key in keys) { var e = await GetEventAsync(key); if (++version != e.Audit.Version) { throw new GangStateVersionException(version, e.Audit); } var method = GangState <TStateData> .ApplyMethods[e.Data.GetType()]; data = method(data, e.Data); } return(GangState.Create(data, version)); }
protected override async Task OnCommandExecutedAsync( IGangCommand command, GangState <HostState> state ) { await base.OnCommandExecutedAsync(command, state); if (!state.HasErrors) { state = state.AddResult( command.Audit.MemberId, new GangNotify( id: command.GetTypeName(), type: GangNotificationTypes.Success, data: new { type = command.GetTypeName(), data = command.Data } ) ); } var results = state.GetResults(command.Audit); foreach (var result in results) { await Controller.SendCommandAsync( result.Command, result.SendToMemberIds, command.Audit.Version ); } }
Task <GangState <TodosState> > IGangCommandHandler <TodosState, object> .HandleAsync(GangState <TodosState> state, GangCommand <object> command) { HandleCalls = HandleCalls.Add(new HandleCall(state, command)); return(Task.FromResult(_getResult(state, command))); }
public CommitCall( string gangId, GangState <TodosState> state, GangAudit audit) { GangId = gangId; State = state; Audit = audit; }
async Task <GangState <TStateData> > IGangStateStore .CommitAsync <TStateData>(string gangId, GangState <TStateData> state, GangAudit audit) { var version = state.Version - (uint)state.Uncommitted.Count; foreach (var eventData in state.Uncommitted) { var e = GangStateEvent.From(eventData, audit); var wrapper = new GangStateEventWrapper( eventData, GangStateEventMap.GetName <TStateData>(eventData.GetType()), audit.SetVersion(++version) ); _events.OnNext(e); var key = GetEventKey(++_sequenceNumber); await _eventStore.SetAsync( key, wrapper, overwrite : false ); } await _cache.SetAsync(gangId, new { state.Data, state.Version } ); await _sequenceNumberStore.SetAsync(KEY_SEQUENCE_NUMBER, _sequenceNumber); return(GangState.Create(state.Data, state.Version)); }
public static string Exists( GangState <HostState> state, string id) { return(state.Data.Users.All(u => u.Id != id) ? ERROR_USER_NOT_FOUND : null); }
static GangState <HostState> GetState() { var state = new HostState( users: new[] { new User(USER_ID) } ); return(GangState.Create(state)); }
public static string NameIsUnique( GangState <HostState> state, string id, string name) { return(state.Data .Users.Any(u => u.Id != id && u.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) ? ERROR_NAME_IS_TAKEN : null); }
public static GangState <HostState> AddUserMessage( this GangState <HostState> state, string text, IEnumerable <string> userIds ) { return(AddUserMessage(state, null, text, userIds)); }
static GangState <HostState> GetState( params User[] users) { var state = new HostState( users: users ); return(GangState.Create(state)); }
public void results() { var state = GangState .Create(TodosState.Initial) .AddResult(MEMBER_ID.GangToBytes(), new GangNotify(id: NOTIFICATION_ID) ); Assert.NotEmpty(state.Results); }
Task <GangState <HostState> > IGangCommandHandler <HostState, AddMessage> .HandleAsync(GangState <HostState> state, GangCommand <AddMessage> command) { return(Task.FromResult( state.AddMessage( command.Data.Id, command.Data.Text, command.Audit.UserId, command.Audit.On ) )); }
public Task <GangState <TodosState> > ExecuteAsync( GangState <TodosState> state, IGangCommand command) { ExecuteCalls = ExecuteCalls .Add(new ExecuteCall( state, command )); return(Task.FromResult( _getResult(state) )); }
Task <GangState <TodosState> > IGangCommandHandler <TodosState, CompleteTodo> .HandleAsync(GangState <TodosState> state, GangCommand <CompleteTodo> command) { return(Task.FromResult( state .Assert(!string.IsNullOrWhiteSpace(command.Audit.UserId), "DENIED") .CompleteTodo(command.Data.Id, DateTimeOffset.Now) .AddResult(command.Audit.MemberId, new GangNotify("Well done", type: GangNotificationTypes.Success)) )); }
public static GangState <HostState> SetUserName( this GangState <HostState> state, string id, string name) { return(state .Assert(User.NameIsValid(name)) .Assert(User.NameIsUnique(state, id, name)) .Assert(User.Exists(state, id)) .RaiseEvent( new UserNameUpdated(id, name), state.Data.Apply )); }
public static GangState <HostState> CreateUser( this GangState <HostState> state, string id, string name) { return(state .Assert(User.NameIsValid(name)) .Assert(User.NameIsUnique(state, id, name)) .Assert(User.DoesNotExist(state, id)) .RaiseEvent( new UserCreated(id, name), state.Data.Apply )); }
async Task <GangState <TStateData> > IGangCommandExecutor <TStateData> .ExecuteAsync(GangState <TStateData> state, IGangCommand command) { var dataTypeName = command.GetTypeName(); if (!_handlers.ContainsKey(dataTypeName)) { throw new GangCommandHandlerNotFoundExcetion(); } var handler = _handlers[dataTypeName]; return(await handler.HandleAsync(state, command)); }
public static GangState <TodosState> AddTodo( this GangState <TodosState> state, string id) { if (state.Data.Todos.ContainsKey(id)) { state.RaiseErrors("id exists"); } return(state.RaiseEvent( new TodoAdded(id), state.Data.Apply )); }
OnStateAsync(GangState <HostState> state) { var members = Controller.GetGang().Members.Where(m => m.Session != null).ToArray(); var usersOnline = state.Data.Users .Where(u => !string.IsNullOrWhiteSpace(u.Name) && members.Any(m => m.Session.User.Id == u.Id)); foreach (var member in members) { var user = state.Data.Users ?.FirstOrDefault(u => u.Id == member.Session.User.Id); if (user == null) { await Controller.SendStateAsync( new { messages = new[] { new Message("Welcome", "Enter your name to join the chat") }, users = Array.Empty <object>() }, new[] { member.Id } ); } else { await Controller.SendStateAsync( new { messages = state.Data .Messages.Concat(user?.Messages.ToImmutableListDefaultEmpty()), users = state.Data.Users.Select(u => new { u.Id, u.Name, isOnline = usersOnline.Contains(u), isCurrent = u.Id == user?.Id }) }, new[] { member.Id } ); } } Console.WriteLine($"State: {JsonConvert.SerializeObject(state, Formatting.Indented)}"); return(await base.OnStateAsync(state)); }
public Task <GangState <TStateData> > CommitAsync <TStateData>( string gangId, GangState <TStateData> state, GangAudit audit) where TStateData : class { var typedState = state as GangState <TodosState>; CommitCalls = CommitCalls.Add( new CommitCall(gangId, typedState, audit)); return(Task.FromResult( new GangState <TStateData>( typedState.Data as TStateData, typedState.Version ) )); }
Task <GangState <TodosState> > IGangCommandHandler <TodosState, AddTodo> .HandleAsync(GangState <TodosState> state, GangCommand <AddTodo> command) { var errors = new List <string>(); if (string.IsNullOrWhiteSpace(command.Audit.UserId)) { errors.Add("Denied"); } return(Task.FromResult( errors.Any() ? state.RaiseErrors(errors) : state.AddTodo(command.Data.Id) )); }
Task <GangState <HostState> > IGangCommandHandler <HostState, UpdateUserName> .HandleAsync(GangState <HostState> state, GangCommand <UpdateUserName> command) { var user = state.Data.Users.TryGetById(command.Audit.UserId); var otherUserIds = state.Data.Users.Where(u => u != user).Select(u => u.Id).ToArray(); if (user == null) { state = state .CreateUser( command.Audit.UserId, command.Data.Name ) .AddUserMessage( "Welcome", $"Hello @{command.Audit.UserId}, welcome to the gang", new[] { command.Audit.UserId } ) .AddUserMessage( $"@{command.Audit.UserId} joined the gang", otherUserIds ); } else { state = user.Name == command.Data.Name ? state : state .SetUserName( command.Audit.UserId, command.Data.Name ) .AddUserMessage( $"{user.Name} changed their name to @{user.Id}", otherUserIds ); } //if (!state.HasErrors) //{ // var gangUser = await _userStore.TryGetByIdAsync(command.Audit.UserId); // await _userStore.SetAsync(gangUser.SetName(command.Data.Name)); //} return(Task.FromResult(state)); }
public static GangState <HostState> AddMessage( this GangState <HostState> state, string id, string text, string byId, DateTimeOffset on ) { id = Message.EnsureId(id); return(state .Assert(User.Exists(state, byId)) .Assert(Message.TextIsRequred(text)) .RaiseEvent( new MessageAdded( id, text, byId, on), state.Data.Apply )); }
public static GangState <TodosState> CompleteTodo( this GangState <TodosState> state, string id, DateTimeOffset on) { if (!state.Data.Todos.ContainsKey(id)) { state.RaiseErrors("id does not exist"); } if (state.Data.Todos[id].CompletedOn.HasValue) { state.RaiseErrors("already complete"); } return(state.RaiseEvent( new TodoCompleted(id, on), state.Data.Apply )); }
public static GangState <HostState> AddUserMessage( this GangState <HostState> state, string id, string text, IEnumerable <string> userIds ) { id = Message.EnsureId(id); return(userIds.Aggregate( state .Assert(Message.TextIsRequred(text)), (s, userId) => s .Assert(User.Exists(s, userId)) .RaiseEvent( new UserMessageAdded( userId, id, text, DateTimeOffset.Now), s.Data.Apply ) )); }
public HandleCall( GangState <TodosState> state, GangCommand <object> command) { State = state; Command = command; }
public ExecuteCall(GangState <TodosState> state, IGangCommand command) { State = state; Command = command; }