private async Task BatchProcessing(List <DataAsyncWrapper <BatchAppendTransport <PrimaryKey>, bool> > wrapperList) { var minTimestamp = wrapperList.Min(t => t.Value.Event.Base.Timestamp); var maxTimestamp = wrapperList.Max(t => t.Value.Event.Base.Timestamp); var minTask = grainConfig.GetCollection(minTimestamp); if (!minTask.IsCompletedSuccessfully) { await minTask; } if (minTask.Result.EndTime > maxTimestamp) { await BatchInsert(minTask.Result.SubTable, wrapperList); } else { var groups = (await Task.WhenAll(wrapperList.Select(async t => { var task = grainConfig.GetCollection(t.Value.Event.Base.Timestamp); if (!task.IsCompletedSuccessfully) { await task; } return(task.Result.SubTable, t); }))).GroupBy(t => t.SubTable); foreach (var group in groups) { await BatchInsert(group.Key, group.Select(g => g.t).ToList()); } } async Task BatchInsert(string collectionName, List <DataAsyncWrapper <BatchAppendTransport <PrimaryKey>, bool> > list) { var collection = grainConfig.Storage.GetCollection <BsonDocument>(grainConfig.DataBase, minTask.Result.SubTable); var documents = list.Select(wrapper => (wrapper, new BsonDocument { { "StateId", BsonValue.Create(wrapper.Value.Event.StateId) }, { "Version", wrapper.Value.Event.Base.Version }, { "Timestamp", wrapper.Value.Event.Base.Timestamp },
private async Task BatchProcessing(List <DataAsyncWrapper <SaveTransport <PrimaryKey>, bool> > wrapperList) { var documents = new List <BsonDocument>(); foreach (var wrapper in wrapperList) { documents.Add(new BsonDocument { { "StateId", BsonValue.Create(wrapper.Value.Event.StateId) }, { "Version", wrapper.Value.Event.Base.Version }, { "Timestamp", wrapper.Value.Event.Base.Timestamp }, { "TypeCode", wrapper.Value.Event.Event.GetType().FullName }, { "Data", Encoding.Default.GetString(wrapper.Value.BytesTransport.EventBytes) }, { "UniqueId", string.IsNullOrEmpty(wrapper.Value.UniqueId) ? wrapper.Value.Event.Base.Version.ToString() : wrapper.Value.UniqueId } }); } var collectionTask = grainConfig.GetCollection(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); if (!collectionTask.IsCompletedSuccessfully) { await collectionTask; } var collection = grainConfig.Storage.GetCollection <BsonDocument>(grainConfig.DataBase, collectionTask.Result.Name); wrapperList.ForEach(wrap => wrap.TaskSource.TrySetResult(true)); try { await collection.InsertManyAsync(documents); wrapperList.ForEach(wrap => wrap.TaskSource.TrySetResult(true)); } catch { foreach (var wrapper in wrapperList) { try { await collection.InsertOneAsync(new BsonDocument { { "StateId", BsonValue.Create(wrapper.Value.Event.StateId) }, { "Version", wrapper.Value.Event.Base.Version }, { "Timestamp", wrapper.Value.Event.Base.Timestamp }, { "TypeCode", wrapper.Value.Event.Event.GetType().FullName }, { "Data", Encoding.Default.GetString(wrapper.Value.BytesTransport.EventBytes) }, { "UniqueId", string.IsNullOrEmpty(wrapper.Value.UniqueId) ? wrapper.Value.Event.Base.Version.ToString() : wrapper.Value.UniqueId } }); wrapper.TaskSource.TrySetResult(true); } catch (MongoWriteException ex) { if (ex.WriteError.Category != ServerErrorCategory.DuplicateKey) { wrapper.TaskSource.TrySetException(ex); } else { wrapper.TaskSource.TrySetResult(false); } } } } }