예제 #1
0
        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));
        }
예제 #2
0
        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)));
        }