public async Task <List <EventInfo <K> > > GetListAsync(K stateId, string typeCode, Int64 startVersion, Int64 endVersion, DateTime?startTime = null) { var collectionList = mongoAttr.GetCollectionList(mongoStorage, mongoStorage.Config.SysStartTime, startTime); var list = new List <EventInfo <K> >(); Int64 readVersion = 0; foreach (var collection in collectionList) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Eq("TypeCode", typeCode) & filterBuilder.Gt("Version", startVersion); var cursor = await mongoStorage.GetCollection <BsonDocument>(mongoAttr.EventDataBase, collection.Name).FindAsync <BsonDocument>(filter, cancellationToken: new CancellationTokenSource(3000).Token); foreach (var document in cursor.ToEnumerable()) { var type = MessageTypeMapper.GetType(typeCode); var data = document["Data"].AsByteArray; var eventInfo = new EventInfo <K>(); eventInfo.IsComplete = document["IsComplete"].AsBoolean; using (MemoryStream ms = new MemoryStream(data)) { var @event = Serializer.Deserialize(type, ms) as IEventBase <K>; eventInfo.Event = @event; } if (readVersion <= endVersion) { list.Add(eventInfo); } } if (readVersion >= endVersion) { break; } } return(list.OrderBy(e => e.Event.Version).ToList()); }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, string typeCode, Int64 startVersion, Int32 limit, DateTime?startTime = null) { var collectionList = grainConfig.GetCollectionList(mongoStorage, mongoStorage.Config.SysStartTime, startTime); var list = new List <IEventBase <K> >(); foreach (var collection in collectionList) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Eq("TypeCode", typeCode) & filterBuilder.Gt("Version", startVersion); var cursor = await mongoStorage.GetCollection <BsonDocument>(grainConfig.EventDataBase, collection.Name).FindAsync <BsonDocument>(filter, cancellationToken: new CancellationTokenSource(10000).Token); foreach (var document in cursor.ToEnumerable()) { var type = MessageTypeMapper.GetType(typeCode); var data = document["Data"].AsByteArray; using (var ms = new MemoryStream(data)) { if (Serializer.Deserialize(type, ms) is IEventBase <K> evt) { list.Add(evt); } } } if (list.Count >= limit) { break; } } return(list); }
public async ValueTask Tell(W message) { if (MessageTypeMapper.TryGetValue(message.TypeCode, out var type)) { using (var ems = new MemoryStream(message.BinaryBytes)) { if (Serializer.Deserialize(type, ems) is IEventBase <K> @event) { if (@event.Version == State.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompleted) { await onEventDeliveredTask; } State.FullUpdateVersion(@event);//更新处理完成的Version } else if (@event.Version > State.Version) { var eventStorageTask = GetEventStorage(); if (!eventStorageTask.IsCompleted) { await eventStorageTask; } var eventList = await eventStorageTask.Result.GetListAsync(GrainId, State.Version, @event.Version, State.VersionTime); foreach (var item in eventList) { var onEventDeliveredTask = OnEventDelivered(item); if (!onEventDeliveredTask.IsCompleted) { await onEventDeliveredTask; } State.FullUpdateVersion(item);//更新处理完成的Version } } if (@event.Version == State.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompleted) { await onEventDeliveredTask; } State.FullUpdateVersion(@event);//更新处理完成的Version } if (@event.Version > State.Version) { throw new Exception($"Event version of the error,Type={GetType().FullName},StateId={this.GrainId.ToString()},StateVersion={State.Version},EventVersion={@event.Version}"); } await SaveSnapshotAsync(); } } } }
protected override void OnRaiseSuccess(IEventBase <K> @event, byte[] bytes) { if (MessageTypeMapper.TryGetValue(@event.GetType().FullName, out var type)) { using (var dms = new MemoryStream(bytes)) { Apply(BackupState, (IEventBase <K>)Serializer.Deserialize(type, dms)); } BackupState.FullUpdateVersion(@event);//更新处理完成的Version } }
public void MappingMessageTypeConventionThrowExceptionIfNotUnique() { void CheckFunction() { var typeconvention = new MessageTypeMapper(); typeconvention.Map <SimpleMessage>("simpleMessage"); typeconvention.Map <SimpleMessageFromOtherBus>("simpleMessage"); } Assert.Throws(typeof(RebusConfigurationException), CheckFunction); }
public static IServiceCollection AddTransacto(this IServiceCollection services, params IPlugin[] plugins) => plugins.Concat(Standard.Plugins).Aggregate(services .AddRouting() .AddSingleton(MessageTypeMapper.Create(Array.ConvertAll(plugins, plugin => new MessageTypeMapper(plugin.MessageTypes)))) // projections .AddSingleton <Func <IPlugin, NpgsqlConnection> >(provider => { var cache = new ConcurrentDictionary <string, NpgsqlConnectionStringBuilder>(); return(plugin => new NpgsqlConnection(cache.GetOrAdd(plugin.Name, username => new NpgsqlConnectionStringBuilder( provider.GetRequiredService <NpgsqlConnectionStringBuilder>().ConnectionString) { Username = username }).ConnectionString)); }), (services, plugin) => { var rootProvider = services.BuildServiceProvider(); var pluginServices = new ServiceCollection(); plugin.ConfigureServices(pluginServices); var pluginProvider = pluginServices .AddSingleton(rootProvider.GetRequiredService <EventStoreClient>()) .AddSingleton(rootProvider.GetRequiredService <IStreamStore>()) .AddSingleton(rootProvider.GetRequiredService <IMessageTypeMapper>()) .AddSingleton <InMemoryProjectionDatabase>() .AddHostedService(provider => new InMemoryProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <InMemoryProjectionDatabase>(), provider.GetServices <ProjectionHandler <InMemoryProjectionDatabase>[]>().ToArray())) .AddSingleton <Func <NpgsqlConnection> >(_ => () => rootProvider .GetRequiredService <Func <IPlugin, NpgsqlConnection> >() .Invoke(plugin)) .AddHostedService(provider => new NpgsqlProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <Func <NpgsqlConnection> >(), provider.GetServices <NpgsqlProjection>().ToArray())) .AddHostedService(provider => new StreamStoreProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <IStreamStore>(), provider.GetServices <StreamStoreProjection>().ToArray())) .BuildServiceProvider(); return(pluginProvider .GetServices <IHostedService>() .Aggregate(services.AddSingleton(Tuple.Create(plugin, (IServiceProvider)pluginProvider)), (services, service) => services.AddSingleton(service))); });
public void MappingMessageTypeConventionUseGetAssExtension() { var typeconvention = new MessageTypeMapper(); typeconvention.Map <SimpleMessage>("simpleMessage"); var typeconventionotherbus = new MessageTypeMapper(); typeconventionotherbus.Map <SimpleMessageFromOtherBus>("simpleMessage"); var expected = typeof(SimpleMessageFromOtherBus); var name = typeconvention.GetMessageType(typeof(SimpleMessage)); var actual = typeconventionotherbus.GetTypeFromMessage(name); Assert.That(actual, Is.EqualTo(expected)); }
public Task Notice(byte[] bytes) { var serializer = serviceProvider.GetService <ISerializer>(); using (var ms = new MemoryStream(bytes)) { var msg = serializer.Deserialize <TMessageWrapper>(ms); if (!MessageTypeMapper.TryGetValue(msg.TypeCode, out var type)) { throw new Exception($"{ msg.TypeCode } does not exist"); } using (var ems = new MemoryStream(msg.BinaryBytes)) { return(Notice(bytes, msg.BinaryBytes, msg, serializer.Deserialize(type, ems))); } } }
public Task Notice(byte[] bytes) { var serializer = serviceProvider.GetService <ISerializer>(); using (var ms = new MemoryStream(bytes)) { var msg = serializer.Deserialize <TMessageWrapper>(ms); var type = MessageTypeMapper.GetType(msg.TypeCode); if (type == null) { throw new Exception($"TypeCode for { msg.TypeCode } type does not exist"); } using (var ems = new MemoryStream(msg.BinaryBytes)) { return(this.Notice(bytes, msg, serializer.Deserialize(type, ems))); } } }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, string typeCode, long startVersion, int limit, DateTime?startTime = null) { var originList = new List <byte[]>(limit); if (MessageTypeMapper.TryGetValue(typeCode, out var type)) { await Task.Run(async() => { var tableList = await tableInfo.GetTableList(startTime); using (var conn = tableInfo.CreateConnection() as NpgsqlConnection) { await conn.OpenAsync(); foreach (var table in tableList) { var sql = $"COPY (SELECT data from {table.Name} WHERE stateid='{stateId.ToString()}' and typecode='{typeCode}' and version>{startVersion} order by version asc limit {limit}) TO STDOUT (FORMAT BINARY)"; using (var reader = conn.BeginBinaryExport(sql)) { while (reader.StartRow() != -1) { originList.Add(reader.Read <byte[]>(NpgsqlDbType.Bytea)); } } if (originList.Count >= limit) { break; } } } }); } var list = new List <IEventBase <K> >(originList.Count); foreach (var origin in originList) { using (var ms = new MemoryStream(origin)) { if (Serializer.Deserialize(type, ms) is IEventBase <K> evt) { list.Add(evt); } } } return(list.OrderBy(v => v.Version).ToList()); }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, Int64 startVersion, Int64 endVersion, DateTime?startTime = null) { var collectionListTask = grainConfig.GetCollectionList(startTime); if (!collectionListTask.IsCompleted) { await collectionListTask; } var list = new List <IEventBase <K> >(); long readVersion = 0; foreach (var collection in collectionListTask.Result) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Lte("Version", endVersion) & filterBuilder.Gt("Version", startVersion); var cursor = await grainConfig.Storage.GetCollection <BsonDocument>(grainConfig.DataBase, collection.Name).FindAsync <BsonDocument>(filter, cancellationToken: new CancellationTokenSource(10000).Token); foreach (var document in cursor.ToEnumerable()) { var typeCode = document["TypeCode"].AsString; if (MessageTypeMapper.TryGetValue(typeCode, out var type)) { var data = document["Data"].AsByteArray; using (var ms = new MemoryStream(data)) { if (Serializer.Deserialize(type, ms) is IEventBase <K> evt) { readVersion = evt.Version; if (readVersion <= endVersion) { list.Add(evt); } } } } } if (readVersion >= endVersion) { break; } } return(list); }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, Int64 startVersion, Int64 endVersion, DateTime?startTime = null) { var tableList = await tableInfo.GetTableList(startTime); var list = new List <IEventBase <K> >(); Int64 readVersion = 0; using (var conn = tableInfo.CreateConnection()) { foreach (var table in tableList) { if (!oneListSqlDict.TryGetValue(table.Name, out var sql)) { sql = $"SELECT typecode,data from {table.Name} WHERE stateid=@StateId and version>@Start and version<=@End order by version asc"; oneListSqlDict.TryAdd(table.Name, sql); } var sqlEventList = await conn.QueryAsync <SqlEvent>(sql, new { StateId = stateId.ToString(), Start = startVersion, End = endVersion }); foreach (var sqlEvent in sqlEventList) { var type = MessageTypeMapper.GetType(sqlEvent.TypeCode); using (var ms = new MemoryStream(sqlEvent.Data)) { if (Serializer.Deserialize(type, ms) is IEventBase <K> evt) { readVersion = evt.Version; if (readVersion <= endVersion) { list.Add(evt); } } } } if (readVersion >= endVersion) { break; } } } return(list); }
public Task ConcurrentTell(byte[] bytes) { using (var wms = new MemoryStream(bytes)) { var message = Serializer.Deserialize <W>(wms); if (MessageTypeMapper.TryGetValue(message.TypeCode, out var type)) { using (var ems = new MemoryStream(message.BinaryBytes)) { if (Serializer.Deserialize(type, ems) is IEventBase <K> @event) { if (@event.Version > State.Version) { return(tellChannel.WriteAsync(@event)); } } } } } return(Task.CompletedTask); }
public async Task <List <EventInfo <K> > > GetListAsync(K stateId, string typeCode, Int64 startVersion, Int64 endVersion, DateTime?startTime = null) { var tableList = await tableInfo.GetTableList(startTime); var list = new List <EventInfo <K> >(); Int64 readVersion = 0; using (var conn = tableInfo.CreateConnection()) { foreach (var table in tableList) { var sql = $"SELECT typecode,data,IsComplete from {table.Name} WHERE stateid=@StateId and typecode=@TypeCode and version>@Start and version<=@End"; var sqlEventList = await conn.QueryAsync <SqlEvent>(sql, new { StateId = stateId, TypeCode = typeCode, Start = startVersion, End = endVersion }); foreach (var sqlEvent in sqlEventList) { var type = MessageTypeMapper.GetType(sqlEvent.TypeCode); var eventInfo = new EventInfo <K>(); eventInfo.IsComplete = sqlEvent.IsComplete; using (var ms = new MemoryStream(sqlEvent.Data)) { var @event = Serializer.Deserialize(type, ms) as IEventBase <K>; readVersion = @event.Version; eventInfo.Event = @event; } if (readVersion <= endVersion) { list.Add(eventInfo); } } if (readVersion >= endVersion) { break; } } } return(list.OrderBy(e => e.Event.Version).ToList()); }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, string typeCode, Int64 startVersion, Int32 limit, DateTime?startTime = null) { var tableList = await tableInfo.GetTableList(startTime); var list = new List <IEventBase <K> >(); using (var conn = tableInfo.CreateConnection()) { foreach (var table in tableList) { if (!twoListSqlDict.TryGetValue(table.Name, out var sql)) { sql = $"SELECT typecode,data from {table.Name} WHERE stateid=@StateId and typecode=@TypeCode and version>@Start order by version asc limit @Limit"; twoListSqlDict.TryAdd(table.Name, sql); } var sqlEventList = await conn.QueryAsync <SqlEvent>(sql, new { StateId = stateId.ToString(), TypeCode = typeCode, Start = startVersion, Limit = limit - list.Count }); foreach (var sqlEvent in sqlEventList) { var type = MessageTypeMapper.GetType(sqlEvent.TypeCode); using (var ms = new MemoryStream(sqlEvent.Data)) { if (Serializer.Deserialize(type, ms) is IEventBase <K> evt) { list.Add(evt); } } } if (list.Count >= limit) { break; } } } return(list); }
public async Task Tell(W message) { var type = MessageTypeMapper.GetType(message.TypeCode); if (type != null) { using (var ems = new MemoryStream(message.BinaryBytes)) { if (Serializer.Deserialize(type, ems) is IEventBase <K> @event) { if (@event.Version == State.Version + 1) { State.IncrementDoingVersion();//标记将要处理的Version try { await OnEventDelivered(@event); State.UpdateVersion(@event);//更新处理完成的Version } catch (Exception e) { State.DoingVersion = State.Version;//标记将要处理的Version ExceptionDispatchInfo.Capture(e).Throw(); } await OnExecuted(@event); await SaveSnapshotAsync(); } else if (@event.Version > State.Version) { var eventList = await EventStorage.GetListAsync(GrainId, State.Version, @event.Version, State.VersionTime); foreach (var item in eventList) { State.IncrementDoingVersion();//标记将要处理的Version try { await OnEventDelivered(item); State.UpdateVersion(item);//更新处理完成的Version } catch (Exception e) { State.DoingVersion = State.Version;//标记将要处理的Version ExceptionDispatchInfo.Capture(e).Throw(); } await OnExecuted(@event); await SaveSnapshotAsync(); } } if (@event.Version == State.Version + 1) { State.IncrementDoingVersion();//标记将要处理的Version try { await OnEventDelivered(@event); State.UpdateVersion(@event);//更新处理完成的Version } catch (Exception e) { State.DoingVersion = State.Version;//标记将要处理的Version ExceptionDispatchInfo.Capture(e).Throw(); } await OnExecuted(@event); await SaveSnapshotAsync(); } if (@event.Version > State.Version) { throw new Exception($"Event version of the error,Type={GetType().FullName},StateId={this.GrainId.ToString()},StateVersion={State.Version},EventVersion={@event.Version}"); } } } } }
public static IServiceCollection AddTransacto(this IServiceCollection services, params IPlugin[] plugins) => plugins.Concat(Standard.Plugins).Aggregate(services .AddRouting() .AddSingleton(MessageTypeMapper.Create(Array.ConvertAll(plugins, plugin => new MessageTypeMapper(plugin.MessageTypes)))) // write model .AddSingleton <CommandHandlerModule>(provider => new GeneralLedgerEntryModule( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), TransactoSerializerOptions.Events, provider.GetRequiredService <ICommandContext>())) .AddSingleton <CommandHandlerModule>(provider => new ChartOfAccountsModule( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), TransactoSerializerOptions.Events)) .AddSingleton <CommandHandlerModule>(provider => new GeneralLedgerModule( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), TransactoSerializerOptions.Events)) // projections .AddSingleton <Func <IPlugin, NpgsqlConnection> >(provider => { var cache = new ConcurrentDictionary <string, NpgsqlConnectionStringBuilder>(); return(plugin => new NpgsqlConnection(cache.GetOrAdd(plugin.Name, username => new NpgsqlConnectionStringBuilder( provider.GetRequiredService <NpgsqlConnectionStringBuilder>().ConnectionString) { Username = username }).ConnectionString)); }) .AddSingleton <Func <IPlugin, InMemoryReadModel> >(provider => { var cache = new ConcurrentDictionary <string, InMemoryReadModel>(); return(plugin => cache.GetOrAdd(plugin.Name, _ => new InMemoryReadModel())); }) .AddHttpContextAccessor() .AddSingleton <ICommandContext, HttpContextCommandContext>(), (services, plugin) => { var rootProvider = services.BuildServiceProvider(); var pluginServices = new ServiceCollection(); plugin.ConfigureServices(pluginServices); var pluginProvider = pluginServices .AddSingleton(rootProvider.GetRequiredService <EventStoreClient>()) .AddSingleton(rootProvider.GetRequiredService <IStreamStore>()) .AddSingleton(rootProvider.GetRequiredService <IMessageTypeMapper>()) .AddSingleton(provider => rootProvider .GetRequiredService <Func <IPlugin, InMemoryReadModel> >().Invoke(plugin)) .AddHostedService(provider => new InMemoryProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <InMemoryReadModel>(), provider.GetServices <ProjectionHandler <InMemoryReadModel>[]>().ToArray())) .AddSingleton <Func <NpgsqlConnection> >(provider => () => rootProvider .GetRequiredService <Func <IPlugin, NpgsqlConnection> >() .Invoke(plugin)) .AddHostedService(provider => new NpgSqlProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <Func <NpgsqlConnection> >(), provider.GetServices <NpgsqlProjection>().ToArray())) .AddHostedService(provider => new StreamStoreProjectionHost( provider.GetRequiredService <EventStoreClient>(), provider.GetRequiredService <IMessageTypeMapper>(), provider.GetRequiredService <IStreamStore>(), provider.GetServices <StreamStoreProjection>().ToArray())) .BuildServiceProvider(); return(pluginProvider .GetServices <IHostedService>() .Aggregate(services.AddSingleton(Tuple.Create(plugin, (IServiceProvider)pluginProvider)), (services, service) => services.AddSingleton(service))); });
public async Task Tell(W message) { var type = MessageTypeMapper.GetType(message.TypeCode); if (type != null) { using (var ems = new MemoryStream(message.BinaryBytes)) { var @event = Serializer.Deserialize(type, ems) as IEventBase <K>; if (@event != null) { if (@event.Version == this.State.Version + 1) { await OnExecution(@event); this.State.IncrementDoingVersion();//标记将要处理的Version try { EventHandle.Apply(this.State, @event); this.State.UpdateVersion(@event);//更新处理完成的Version } catch (Exception e) { this.State.DoingVersion = this.State.Version;//标记将要处理的Version throw e; } await OnExecuted(@event); await SaveSnapshotAsync(); } else if (@event.Version > this.State.Version) { var eventList = await EventStorage.GetListAsync(this.GrainId, this.State.Version, @event.Version); foreach (var item in eventList) { await OnExecution(item.Event); this.State.IncrementDoingVersion();//标记将要处理的Version try { EventHandle.Apply(this.State, item.Event); this.State.UpdateVersion(item.Event);//更新处理完成的Version } catch (Exception e) { this.State.DoingVersion = this.State.Version;//标记将要处理的Version throw e; } await OnExecuted(item.Event); await SaveSnapshotAsync(); } } if (@event.Version == this.State.Version + 1) { await OnExecution(@event); this.State.IncrementDoingVersion();//标记将要处理的Version try { EventHandle.Apply(this.State, @event); this.State.UpdateVersion(@event);//更新处理完成的Version } catch (Exception e) { this.State.DoingVersion = this.State.Version;//标记将要处理的Version throw e; } await OnExecuted(@event); await SaveSnapshotAsync(); } if (@event.Version > this.State.Version) { throw new Exception($"Event version of the error,Type={ThisType.FullName},StateId={this.GrainId.ToString()},StateVersion={this.State.Version},EventVersion={@event.Version}"); } } } } }