public Task Write(IList <MatcherEntry> entriesToPersist) { if (entriesToPersist.Count == 0) { return(Task.CompletedTask); } var fattestMessage = entriesToPersist.OrderByDescending(msg => msg.MessageBytes?.Length ?? 0).First(); _reporter.AddStorageReport(entriesToPersist.Count, entriesToPersist.Sum(msg => msg.MessageBytes?.Length ?? 0), fattestMessage.MessageBytes?.Length ?? 0, fattestMessage.MessageTypeName); var insertTasks = new List <Task>(entriesToPersist.Count); var countByPeer = new Dictionary <PeerId, int>(); foreach (var matcherEntry in entriesToPersist) { var shouldInvestigatePeer = _configuration.PeerIdsToInvestigate != null && _configuration.PeerIdsToInvestigate.Contains(matcherEntry.PeerId.ToString()); if (shouldInvestigatePeer) { _log.Info($"Storage requested for peer {matcherEntry.PeerId}, Type: {matcherEntry.Type}, Message Id: {matcherEntry.MessageId}"); } var messageDateTime = matcherEntry.MessageId.GetDateTimeForV2OrV3(); var rowTimestamp = matcherEntry.IsAck ? messageDateTime.AddTicks(10) : messageDateTime; var insertTask = _parallelPersistor.Insert(_preparedStatement.Bind(matcherEntry.PeerId.ToString(), BucketIdHelper.GetBucketId(messageDateTime), messageDateTime.Ticks, matcherEntry.MessageId.Value, matcherEntry.IsAck, matcherEntry.MessageBytes, (int)PersistentMessagesTimeToLive.TotalSeconds, ToUnixMicroSeconds(rowTimestamp))); if (shouldInvestigatePeer) { insertTask = insertTask.ContinueWith(t => _log.Info($"Storage done for peer {matcherEntry.PeerId}, Type: {matcherEntry.Type}, Message Id: {matcherEntry.MessageId}, TaskResult: {t.Status}")); } insertTasks.Add(insertTask); var countDelta = matcherEntry.IsAck ? -1 : 1; countByPeer[matcherEntry.PeerId] = countDelta + countByPeer.GetValueOrDefault(matcherEntry.PeerId); if (shouldInvestigatePeer) { _log.Info($"Count delta computed for peer {matcherEntry.PeerId}, will increment: {countDelta}"); } } foreach (var countForPeer in countByPeer) { _peerStateRepository.UpdateNonAckMessageCount(countForPeer.Key, countForPeer.Value); } return(Task.WhenAll(insertTasks)); }
public Task Write(IList <MatcherEntry> entriesToPersist) { if (entriesToPersist.Count == 0) { return(Task.CompletedTask); } var fattestMessage = entriesToPersist.OrderByDescending(msg => msg.MessageBytes?.Length ?? 0).First(); _reporter.AddStorageReport(entriesToPersist.Count, entriesToPersist.Sum(msg => msg.MessageBytes?.Length ?? 0), fattestMessage.MessageBytes?.Length ?? 0, fattestMessage.MessageTypeName); var countByPeer = new Dictionary <PeerId, int>(); foreach (var matcherEntry in entriesToPersist) { var shouldInvestigatePeer = _configuration.PeerIdsToInvestigate != null && _configuration.PeerIdsToInvestigate.Contains(matcherEntry.PeerId.ToString()); if (shouldInvestigatePeer) { _log.Info($"Storage requested for peer {matcherEntry.PeerId}, Type: {matcherEntry.Type}, Message Id: {matcherEntry.MessageId}"); } var countDelta = matcherEntry.IsAck ? -1 : 1; countByPeer[matcherEntry.PeerId] = countDelta + countByPeer.GetValueOrDefault(matcherEntry.PeerId); if (shouldInvestigatePeer) { _log.Info($"Count delta computed for peer {matcherEntry.PeerId}, will increment: {countDelta}"); } } var insertTasks = new List <Task>(); var remaining = new SemaphoreSlim(_maxParallelInsertTasks); foreach (var matcherEntry in entriesToPersist) { var gotSlot = remaining.Wait(TimeSpan.FromSeconds(10)); if (!gotSlot) { _log.Warn("Could not get slot to insert in cassandra after 10 second."); } var messageDateTime = matcherEntry.MessageId.GetDateTimeForV2OrV3(); var rowTimestamp = matcherEntry.IsAck ? messageDateTime.AddTicks(10) : messageDateTime; var boundStatement = _preparedStatement.Bind(matcherEntry.PeerId.ToString(), BucketIdHelper.GetBucketId(messageDateTime), messageDateTime.Ticks, matcherEntry.MessageId.Value, matcherEntry.IsAck, matcherEntry.MessageBytes, (int)PeerState.MessagesTimeToLive.TotalSeconds, ToUnixMicroSeconds(rowTimestamp)); var insertTask = _dataContext.Session.ExecuteAsync(boundStatement); insertTasks.Add(insertTask); insertTask.ContinueWith(t => { var shouldInvestigatePeer = _configuration.PeerIdsToInvestigate != null && _configuration.PeerIdsToInvestigate.Contains(matcherEntry.PeerId.ToString()); if (shouldInvestigatePeer) { _log.Info($"Storage done for peer {matcherEntry.PeerId}, Type: {matcherEntry.Type}, Message Id: {matcherEntry.MessageId}, TaskResult: {t.Status}"); } if (t.IsFaulted) { _log.Error(t.Exception); } remaining.Release(); }, TaskContinuationOptions.ExecuteSynchronously); } var updateNonAckedCountTasks = new List <Task>(); foreach (var countForPeer in countByPeer) { updateNonAckedCountTasks.Add(_peerStateRepository.UpdateNonAckMessageCount(countForPeer.Key, countForPeer.Value)); } return(Task.WhenAll(insertTasks.Concat(updateNonAckedCountTasks))); }