private async ValueTask FlowProcess() { var start = DateTime.UtcNow; var wrapList = new List <EventBytesTransactionWrap <K> >(); var documents = new List <MongoEvent <K> >(); while (EventSaveFlowChannel.TryReceive(out var evt)) { wrapList.Add(evt); documents.Add(new MongoEvent <K> { Id = new ObjectId(), StateId = evt.Value.StateId, Version = evt.Value.Version, TypeCode = evt.Value.GetType().FullName, Data = evt.Bytes, UniqueId = string.IsNullOrEmpty(evt.UniqueId) ? evt.Value.Version.ToString() : evt.UniqueId }); if ((DateTime.UtcNow - start).TotalMilliseconds > 100) { break; //保证批量延时不超过100ms } } var collectionTask = grainConfig.GetCollection(DateTime.UtcNow); if (!collectionTask.IsCompleted) { await collectionTask; } var collection = grainConfig.Storage.GetCollection <MongoEvent <K> >(grainConfig.DataBase, collectionTask.Result.Name); wrapList.ForEach(wrap => wrap.TaskSource.TrySetResult(true)); try { await collection.InsertManyAsync(documents); wrapList.ForEach(wrap => wrap.TaskSource.TrySetResult(true)); } catch { foreach (var w in wrapList) { try { await collection.InsertOneAsync(new MongoEvent <K> { Id = new ObjectId(), StateId = w.Value.StateId, Version = w.Value.Version, TypeCode = w.Value.GetType().FullName, Data = w.Bytes, UniqueId = string.IsNullOrEmpty(w.UniqueId) ? w.Value.Version.ToString() : w.UniqueId }); w.TaskSource.TrySetResult(true); } catch (MongoWriteException ex) { if (ex.WriteError.Category != ServerErrorCategory.DuplicateKey) { w.TaskSource.TrySetException(ex); } else { w.TaskSource.TrySetResult(false); } } } } }
public async Task <bool> SaveAsync(IEventBase <K> data, byte[] bytes, string uniqueId = null) { var mEvent = new MongoEvent <K> { StateId = data.StateId, Version = data.Version, TypeCode = data.TypeCode, Data = bytes }; mEvent.Id = data.Id; if (string.IsNullOrEmpty(uniqueId)) { mEvent.MsgId = mEvent.Id; } else { mEvent.MsgId = uniqueId; } try { await mongoStorage.GetCollection <MongoEvent <K> >(grainConfig.EventDataBase, grainConfig.GetCollection(mongoStorage, mongoStorage.Config.SysStartTime, data.Timestamp).Name).InsertOneAsync(mEvent); return(true); } catch (MongoWriteException ex) { if (ex.WriteError.Category != ServerErrorCategory.DuplicateKey) { throw ex; } else { logger.LogError(ex, $"事件重复插入,Event:{Newtonsoft.Json.JsonConvert.SerializeObject(data)}"); } } return(false); }