예제 #1
0
파일: AsyncGrain.cs 프로젝트: zale1989/Ray
        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();
                    }
                }
            }
        }
예제 #2
0
 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
     }
 }
예제 #3
0
파일: SubHandler.cs 프로젝트: zale1989/Ray
        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)));
                }
            }
        }
예제 #4
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);

            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());
        }
예제 #5
0
        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);
        }
예제 #6
0
파일: AsyncGrain.cs 프로젝트: zale1989/Ray
 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);
 }