public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, string typeCode, Int64 startVersion, Int32 limit, DateTime?startTime = null) { var collectionListTask = grainConfig.GetCollectionList(startTime); if (!collectionListTask.IsCompleted) { await collectionListTask; } var list = new List <IEventBase <K> >(); foreach (var collection in collectionListTask.Result) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Eq("TypeCode", typeCode) & 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 data = document["Data"].AsByteArray; using (var ms = new MemoryStream(data)) { if (Serializer.Deserialize(TypeContainer.GetType(typeCode), ms) is IEventBase <K> evt) { list.Add(evt); } } } if (list.Count >= limit) { break; } } return(list); }
public Task Tell(byte[] bytes) { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes); if (success) { var eventType = TypeContainer.GetType(transport.EventType); var data = Serializer.Deserialize(eventType, transport.EventBytes); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Base.Version) { var tellTask = Tell(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { return(tellTask.AsTask()); } } } else { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventType); } } } return(Task.CompletedTask); }
public async Task OnNext(Immutable <List <byte[]> > items) { var events = items.Value.Select(bytes => { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes); if (success) { var eventType = TypeContainer.GetType(transport.EventTypeCode); var data = Serializer.Deserialize(transport.EventBytes, eventType); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Base.Version) { return(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); } } else { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Non-Event: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType)); } } } return(default);
public Task OnNext(Immutable <byte[]> bytes) { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value); if (success) { var eventType = TypeContainer.GetType(transport.EventTypeCode); var data = Serializer.Deserialize(transport.EventBytes, eventType); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Base.Version) { var tellTask = Tell(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { return(tellTask.AsTask()); } } } else { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Non-event messages:{0}({1})", eventType, Serializer.Serialize(data)); } } } return(Task.CompletedTask); }
public ObserverUnit <PrimaryKey> UnreliableObserver(string group, Func <IServiceProvider, IFullyEvent <PrimaryKey>, ValueTask> handler) { var funcs = GetEventHandlers(group); funcs.Add(func); eventHandlers.Add(func); return(this); //内部函数 Task func(byte[] bytes) { var(success, transport) = EventBytesTransport.FromBytes <PrimaryKey>(bytes); if (success) { var data = serializer.Deserialize(TypeContainer.GetType(transport.EventTypeCode), transport.EventBytes); if (data is IEvent @event && transport.GrainId is PrimaryKey actorId) { var eventBase = EventBase.FromBytes(transport.BaseBytes); var tellTask = handler(serviceProvider, new FullyEvent <PrimaryKey> { StateId = actorId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { return(tellTask.AsTask()); } } } return(Task.CompletedTask); } }
public async Task OnNext(Immutable <byte[]> bytes) { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value); if (success) { var data = Serializer.Deserialize(TypeContainer.GetType(transport.EventTypeCode), transport.EventBytes); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Version) { if (concurrent) { var input = new AsyncInputEvent <IFullyEvent <PrimaryKey>, bool>(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); var writeTask = ConcurrentChannel.WriteAsync(input); if (!writeTask.IsCompletedSuccessfully) { await writeTask; } if (!writeTask.Result) { var ex = new ChannelUnavailabilityException(GrainId.ToString(), GrainType); Logger.LogError(ex, ex.Message); throw ex; } await input.TaskSource.Task; } else { var tellTask = Tell(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { await tellTask; } } } } else { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventTypeCode); } } } }
public Task Notice(byte[] bytes) { var serializer = serviceProvider.GetService <ISerializer>(); using (var ms = new MemoryStream(bytes)) { var msg = serializer.Deserialize <TMessageWrapper>(ms); using (var ems = new MemoryStream(msg.Bytes)) { return(Notice(bytes, msg.Bytes, msg, serializer.Deserialize(TypeContainer.GetType(msg.TypeName), ems))); } } }
public async ValueTask Tell(W message) { using (var ems = new MemoryStream(message.Bytes)) { if (Serializer.Deserialize(TypeContainer.GetType(message.TypeName), ems) is IEventBase <K> @event) { if (@event.Version == State.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompleted) { await onEventDeliveredTask; } State.FullUpdateVersion(@event, GrainType);//更新处理完成的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, GrainType);//更新处理完成的Version } } if (@event.Version == State.Version + 1) { var onEventDeliveredTask = OnEventDelivered(@event); if (!onEventDeliveredTask.IsCompleted) { await onEventDeliveredTask; } State.FullUpdateVersion(@event, GrainType);//更新处理完成的Version } if (@event.Version > State.Version) { throw new EventVersionNotMatchStateException(GrainId.ToString(), GetType(), @event.Version, State.Version); } await SaveSnapshotAsync(); } } }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetList(PrimaryKey stateId, long latestTimestamp, long startVersion, long endVersion) { var list = new List <IFullyEvent <PrimaryKey> >((int)(endVersion - startVersion)); await Task.Run(async() => { var getTableListTask = tableInfo.TableRepository.GetTableListFromDb(); if (!getTableListTask.IsCompletedSuccessfully) { await getTableListTask; } var tableList = getTableListTask.Result; if (latestTimestamp != 0) { tableList = tableList.Where(t => t.Version >= tableInfo.GetVersion(latestTimestamp)).ToList(); } using (var conn = tableInfo.CreateConnection() as NpgsqlConnection) { await conn.OpenAsync(); foreach (var table in tableList) { var sql = $"COPY (SELECT typecode,data,version,timestamp from {table.Name} WHERE stateid='{stateId.ToString()}' and version>={startVersion} and version<={endVersion} order by version asc) TO STDOUT (FORMAT BINARY)"; using (var reader = conn.BeginBinaryExport(sql)) { while (reader.StartRow() != -1) { var typeCode = reader.Read <string>(NpgsqlDbType.Varchar); var data = reader.Read <string>(NpgsqlDbType.Jsonb); var version = reader.Read <long>(NpgsqlDbType.Bigint); var timestamp = reader.Read <long>(NpgsqlDbType.Bigint); if (version <= endVersion && version >= startVersion) { if (serializer.Deserialize(TypeContainer.GetType(typeCode), Encoding.Default.GetBytes(data)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(version, timestamp) }); } } } } } } }); return(list.OrderBy(e => e.Base.Version).ToList()); }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetListByType(PrimaryKey stateId, string typeCode, long startVersion, int limit) { var type = TypeContainer.GetType(typeCode); var list = new List <IFullyEvent <PrimaryKey> >(limit); await Task.Run(async() => { var getTableListTask = config.GetSubTables(); if (!getTableListTask.IsCompletedSuccessfully) { await getTableListTask; } var stateIdStr = typeof(PrimaryKey) == typeof(long) ? stateId.ToString() : $"'{stateId.ToString()}'"; using (var conn = config.CreateConnection() as NpgsqlConnection) { await conn.OpenAsync(); foreach (var table in getTableListTask.Result) { var sql = $"COPY (SELECT data,version,timestamp from {table.SubTable} WHERE stateid={stateIdStr} 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) { var data = reader.Read <string>(NpgsqlDbType.Json); var version = reader.Read <long>(NpgsqlDbType.Bigint); var timestamp = reader.Read <long>(NpgsqlDbType.Bigint); if (version >= startVersion && serializer.Deserialize(type, Encoding.Default.GetBytes(data)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(version, timestamp) }); } } } if (list.Count >= limit) { break; } } } }); return(list.OrderBy(e => e.Base.Version).ToList()); }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetListByType(PrimaryKey stateId, string typeCode, long startVersion, int limit) { var type = TypeContainer.GetType(typeCode); var list = new List <IFullyEvent <PrimaryKey> >(limit); await Task.Run(async() => { var getTableListTask = config.GetSubTables(); if (!getTableListTask.IsCompletedSuccessfully) { await getTableListTask; } using (var conn = config.CreateConnection()) { await conn.OpenAsync(); foreach (var table in getTableListTask.Result) { var sql = $"SELECT data,version,timestamp from {table.SubTable} WHERE stateid=@StateId and typecode=@TypeCode and version>=@StartVersion order by version asc limit @Limit"; var originList = await conn.QueryAsync <EventModel>(sql, new { StateId = stateId, TypeCode = typeCode, StartVersion = startVersion, Limit = limit }); foreach (var item in originList) { if (serializer.Deserialize(type, Encoding.Default.GetBytes(item.Data)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(item.Version, item.Timestamp) }); } } if (list.Count >= limit) { break; } } } }); return(list.OrderBy(e => e.Base.Version).ToList()); }
public Task ConcurrentTell(byte[] bytes) { using (var wms = new MemoryStream(bytes)) { var message = Serializer.Deserialize <W>(wms); using (var ems = new MemoryStream(message.Bytes)) { if (Serializer.Deserialize(TypeContainer.GetType(message.TypeName), ems) is IEventBase <K> @event) { if (@event.Version > State.Version) { return(tellChannel.WriteAsync(@event)); } } } } return(Task.CompletedTask); }
public async Task <IList <IEventBase <K> > > GetListAsync(K stateId, string typeCode, long startVersion, int limit, DateTime?startTime = null) { var originList = new List <byte[]>(limit); var type = TypeContainer.GetType(typeCode); 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 ConcurrentTell(byte[] bytes) { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes); if (success) { var data = Serializer.Deserialize(TypeContainer.GetType(transport.EventType), transport.EventBytes); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Version) { var writeTask = ConcurrentChannel.WriteAsync(new DataAsyncWrapper <IFullyEvent <PrimaryKey>, bool>(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event })); if (!writeTask.IsCompletedSuccessfully) { await writeTask; } if (!writeTask.Result) { var ex = new ChannelUnavailabilityException(GrainId.ToString(), GrainType); if (Logger.IsEnabled(LogLevel.Error)) { Logger.LogError(LogEventIds.TransactionGrainCurrentInput, ex, ex.Message); } throw ex; } } } else { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation(LogEventIds.FollowEventProcessing, "Receive non-event messages, grain Id = {0} ,message type = {1}", GrainId.ToString(), transport.EventType); } } } }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetList(PrimaryKey stateId, long latestTimestamp, long startVersion, long endVersion) { var list = new List <IFullyEvent <PrimaryKey> >((int)(endVersion - startVersion)); await Task.Run(async() => { var getTableListTask = config.GetSubTables(); if (!getTableListTask.IsCompletedSuccessfully) { await getTableListTask; } var stateIdStr = typeof(PrimaryKey) == typeof(long) ? stateId.ToString() : $"'{stateId.ToString()}'"; using (var conn = config.CreateConnection()) { await conn.OpenAsync(); foreach (var table in getTableListTask.Result.Where(t => t.EndTime >= latestTimestamp)) { var sql = $"SELECT typecode,data,version,timestamp from {table.SubTable} WHERE stateid=@StateId and version>=@StartVersion and version<=@EndVersion order by version asc"; var originList = await conn.QueryAsync <EventModel>(sql, new { StateId = stateId, StartVersion = startVersion, EndVersion = endVersion }); foreach (var item in originList) { if (serializer.Deserialize(TypeContainer.GetType(item.TypeCode), Encoding.Default.GetBytes(item.Data)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(item.Version, item.Timestamp) }); } } } } }); return(list.OrderBy(e => e.Base.Version).ToList()); }
public async Task <IList <FullyEvent <PrimaryKey> > > GetList(PrimaryKey stateId, long latestTimestamp, long startVersion, long endVersion) { var list = new List <FullyEvent <PrimaryKey> >((int)(endVersion - startVersion)); await Task.Run(async() => { var getTableListTask = config.GetSubTables(); if (!getTableListTask.IsCompletedSuccessfully) { await getTableListTask; } var stateIdStr = typeof(PrimaryKey) == typeof(long) ? stateId.ToString() : $"'{stateId.ToString()}'"; using var conn = config.CreateConnection() as NpgsqlConnection; await conn.OpenAsync(); foreach (var table in getTableListTask.Result.Where(t => t.EndTime >= latestTimestamp)) { var sql = $"COPY (SELECT typecode,data,version,timestamp from {table.SubTable} WHERE stateid={stateIdStr} and version>={startVersion} and version<={endVersion} order by version asc) TO STDOUT (FORMAT BINARY)"; using var reader = conn.BeginBinaryExport(sql); while (reader.StartRow() != -1) { var typeCode = reader.Read <string>(NpgsqlDbType.Varchar); var data = reader.Read <string>(NpgsqlDbType.Json); var version = reader.Read <long>(NpgsqlDbType.Bigint); var timestamp = reader.Read <long>(NpgsqlDbType.Bigint); if (version <= endVersion && version >= startVersion) { if (serializer.Deserialize(Encoding.UTF8.GetBytes(data), TypeContainer.GetType(typeCode)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(version, timestamp) }); } } } } }); return(list.OrderBy(e => e.Base.Version).ToList()); }
public Task OnNext(Immutable <byte[]> bytes) { var(success, transport) = EventBytesTransport.FromBytesWithNoId(bytes.Value); if (success) { var eventType = TypeContainer.GetType(transport.EventTypeCode); var data = Serializer.Deserialize(transport.EventBytes, eventType); if (data is IEvent @event) { var eventBase = EventBase.FromBytes(transport.BaseBytes); if (eventBase.Version > Snapshot.Base.Version) { var tellTask = Tell(new FullyEvent <PrimaryKey> { StateId = GrainId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { return(tellTask.AsTask()); } } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("OnNext completed: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType)); } } else { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace("Non-Event: {0}->{1}->{2}", GrainType.FullName, GrainId.ToString(), Serializer.Serialize(data, eventType)); } } } return(Task.CompletedTask); }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetListByType(PrimaryKey stateId, string typeCode, long startVersion, int limit) { var collectionListTask = grainConfig.GetCollectionList(); if (!collectionListTask.IsCompletedSuccessfully) { await collectionListTask; } var list = new List <IFullyEvent <PrimaryKey> >(); foreach (var collection in collectionListTask.Result) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Eq("TypeCode", typeCode) & filterBuilder.Gte("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 data = document["Data"].AsString; var timestamp = document["Timestamp"].AsInt64; var version = document["Version"].AsInt64; if (version >= startVersion && serializer.Deserialize(TypeContainer.GetType(typeCode), Encoding.Default.GetBytes(data)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(version, timestamp) }); } } if (list.Count >= limit) { break; } } return(list); }
public async Task <IList <IFullyEvent <PrimaryKey> > > GetList(PrimaryKey stateId, long latestTimestamp, long startVersion, long endVersion) { var collectionListTask = grainConfig.GetCollectionList(); if (!collectionListTask.IsCompletedSuccessfully) { await collectionListTask; } var list = new List <IFullyEvent <PrimaryKey> >(); foreach (var collection in collectionListTask.Result.Where(c => c.EndTime >= latestTimestamp)) { var filterBuilder = Builders <BsonDocument> .Filter; var filter = filterBuilder.Eq("StateId", stateId) & filterBuilder.Lte("Version", endVersion) & filterBuilder.Gte("Version", startVersion); var cursor = await grainConfig.Client.GetCollection <BsonDocument>(grainConfig.DataBase, collection.SubTable).FindAsync <BsonDocument>(filter, cancellationToken: new CancellationTokenSource(10000).Token); foreach (var document in cursor.ToEnumerable()) { var typeCode = document["TypeCode"].AsString; var data = document["Data"].AsString; var timestamp = document["Timestamp"].AsInt64; var version = document["Version"].AsInt64; if (version <= endVersion && version >= startVersion) { if (serializer.Deserialize(Encoding.UTF8.GetBytes(data), TypeContainer.GetType(typeCode)) is IEvent evt) { list.Add(new FullyEvent <PrimaryKey> { StateId = stateId, Event = evt, Base = new EventBase(version, timestamp) }); } } } } return(list); }
public ObserverUnit <PrimaryKey> UnreliableObserver( string group, Func <IServiceProvider, FullyEvent <PrimaryKey>, ValueTask> handler) { GetEventHandlers(group).Add(EventHandler); GetBatchEventHandlers(group).Add(BatchEventHandler); eventHandlers.Add(EventHandler); batchEventHandlers.Add(BatchEventHandler); return(this); //内部函数 Task EventHandler(byte[] bytes) { var(success, transport) = EventBytesTransport.FromBytes <PrimaryKey>(bytes); if (success) { var data = serializer.Deserialize(transport.EventBytes, TypeContainer.GetType(transport.EventTypeCode)); if (data is IEvent @event && transport.GrainId is PrimaryKey actorId) { var eventBase = EventBase.FromBytes(transport.BaseBytes); var tellTask = handler(serviceProvider, new FullyEvent <PrimaryKey> { StateId = actorId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { return(tellTask.AsTask()); } } } return(Task.CompletedTask); } Task BatchEventHandler(List <byte[]> list) { var groups = list.Select(b => EventBytesTransport.FromBytes <PrimaryKey>(b)) .Where(o => o.success) .Select(o => o.transport) .GroupBy(o => o.GrainId); return(Task.WhenAll(groups.Select(async kv => { foreach (var transport in kv) { var data = serializer.Deserialize(transport.EventBytes, TypeContainer.GetType(transport.EventTypeCode)); if (data is IEvent @event && transport.GrainId is PrimaryKey actorId) { var eventBase = EventBase.FromBytes(transport.BaseBytes); var tellTask = handler(serviceProvider, new FullyEvent <PrimaryKey> { StateId = actorId, Base = eventBase, Event = @event }); if (!tellTask.IsCompletedSuccessfully) { await tellTask; } } } }))); } }