public Task WriteAsync(LogBatch data) { var toSend = data.NonNull(nameof(data)).Data.NonNull(nameof(data)); if (!Running) { return(Task.CompletedTask); } var cLog = m_LogDb[COLLECTION_LOG]; int i = 0; using (var errors = new ErrorLogBatcher(App.Log) { Type = MessageType.Critical, From = this.ComponentLogFromPrefix + nameof(WriteAsync), Topic = ComponentLogTopic }) foreach (var batch in toSend.BatchBy(0xf)) { var bsons = batch.Select(msg => { if (msg.Gdid.IsZero) { msg.Gdid = m_Gdid.Provider.GenerateOneGdid(scopeName: SysConsts.GDID_NS_CHRONICLES, sequenceName: COLLECTION_LOG); } if (msg.Guid == Guid.Empty) { msg.Guid = Guid.NewGuid(); } return(BsonConvert.ToBson(msg)); }); try { var result = cLog.Insert(bsons.ToArray()); if (result.WriteErrors != null) { result.WriteErrors.ForEach(we => new MongoDbConnectorServerException(we.Message)); } } catch (Exception genError) { errors.Add(genError); } if (!Running) { break; } if (++i > MAX_INSERT_DOC_COUNT) { WriteLog(MessageType.Critical, nameof(WriteAsync), "LogBatch exceeds max allowed count of {0}. The rest discarded".Args(MAX_INSERT_DOC_COUNT)); break; } } return(Task.CompletedTask); }
public async Task WriteAsync(LogBatch data) { data.NonNull(nameof(data)) .Data .NonNull(nameof(data.Data)); //0 Prepare messages for insertion GDID[] gdids = null; Exception gdidFailure = null; for (int i = 0, j = 0; i < data.Data.Length; i++) { var msg = data.Data[i]; if (gdidFailure == null) { if (gdids == null || j == gdids.Length) { try { j = 0; gdids = m_Gdid.Provider.TryGenerateManyConsecutiveGdids(scopeName: SysConsts.GDID_NS_CHRONICLES, sequenceName: SEQ_SKY_LOG, gdidCount: data.Data.Length - i); } catch (Exception error) { gdidFailure = error; } } } if (gdidFailure == null) { //gdid regenerated msg.Gdid = gdids[j++]; } msg.InitDefaultFields(App); } //1 Write to archive graph ASAP Exception archiveFailure = null; try { var arch = m_LogArchiveGraph; if (arch != null) { data.Data.ForEach(m => arch.Write(m)); } } catch (Exception error) { archiveFailure = error; } //2 Write to store Exception storeFailure = null; try { await m_Log.NonNull().WriteAsync(data); } catch (Exception error) { storeFailure = error; } //catastrophic notification may trigger something like SolarWind/Everbridge et.al. alert if (gdidFailure != null) { WriteLog(MessageType.CatastrophicError, nameof(WriteAsync), "Gdid generation failed: " + gdidFailure.ToMessageWithType(), gdidFailure, Ambient.CurrentCallFlow?.ID); } if (archiveFailure != null) { WriteLog(MessageType.CatastrophicError, nameof(WriteAsync), "Archive failed: " + archiveFailure.ToMessageWithType(), archiveFailure, Ambient.CurrentCallFlow?.ID); } if (storeFailure != null) { WriteLog(MessageType.CatastrophicError, nameof(WriteAsync), "Store failed: " + storeFailure.ToMessageWithType(), storeFailure, Ambient.CurrentCallFlow?.ID); } }