예제 #1
0
        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);
        }
예제 #2
0
파일: ReplicaGrain.cs 프로젝트: pangfd/Ray
 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);
 }
예제 #3
0
 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);
예제 #4
0
 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);
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
 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);
             }
         }
     }
 }
예제 #7
0
파일: SubHandler.cs 프로젝트: zhrjin/Ray
        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)));
                }
            }
        }
예제 #8
0
        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();
                }
            }
        }
예제 #9
0
        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());
        }
예제 #10
0
        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());
        }
예제 #11
0
        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());
        }
예제 #12
0
 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);
 }
예제 #13
0
        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());
        }
예제 #14
0
 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);
             }
         }
     }
 }
예제 #15
0
        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());
        }
예제 #16
0
        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());
        }
예제 #17
0
 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);
 }
예제 #18
0
파일: EventStorage.cs 프로젝트: zszqwe/Ray
        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);
        }
예제 #19
0
파일: EventStorage.cs 프로젝트: zz110/Ray
        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);
        }
예제 #20
0
        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;
                            }
                        }
                    }
                })));
            }
        }