예제 #1
0
        public void Should_escape_correctly(string partitionKey)
        {
            var escapedKey = PartitionKeyEscapeHelper.Escape(partitionKey);

            escapedKey.Should().NotContain("/");
            var originalKey = PartitionKeyEscapeHelper.Unescape(escapedKey);

            originalKey.Should().Be(partitionKey);
        }
        public override async Task ReplayMessagesAsync(
            IActorContext context,
            string persistenceId,
            long fromSequenceNr,
            long toSequenceNr,
            long max,
            Action <IPersistentRepresentation> recoveryCallback)
        {
            NotifyNewPersistenceIdAdded(persistenceId);

            _log.Debug("Entering method ReplayMessagesAsync for persistentId [{0}] from seqNo range [{1}, {2}] and taking up to max [{3}]", persistenceId, fromSequenceNr, toSequenceNr, max);

            if (max == 0)
            {
                return;
            }

            var replayQuery = GeneratePersistentJournalEntryReplayQuery(persistenceId, fromSequenceNr, toSequenceNr);

            var nextTask = Table.ExecuteQuerySegmentedAsync(replayQuery, null);
            var count    = 0L;

            while (nextTask != null)
            {
                var tableQueryResult = await nextTask;

                if (_log.IsDebugEnabled && _settings.VerboseLogging)
                {
                    _log.Debug("Recovered [{0}] messages for entity [{1}]", tableQueryResult.Results.Count, persistenceId);
                }

                if (tableQueryResult.ContinuationToken != null)
                {
                    if (_log.IsDebugEnabled && _settings.VerboseLogging)
                    {
                        _log.Debug("Have additional messages to download for entity [{0}]", persistenceId);
                    }
                    // start the next query while we process the results of this one
                    nextTask = Table.ExecuteQuerySegmentedAsync(replayQuery, tableQueryResult.ContinuationToken);
                }
                else
                {
                    if (_log.IsDebugEnabled && _settings.VerboseLogging)
                    {
                        _log.Debug("Completed download of messages for entity [{0}]", persistenceId);
                    }

                    // terminates the loop
                    nextTask = null;
                }

                foreach (var savedEvent in tableQueryResult.Results)
                {
                    // check if we've hit max recovery
                    if (count >= max)
                    {
                        return;
                    }
                    ++count;

                    var deserialized = _serialization.PersistentFromBytes(savedEvent.Payload);

                    // Write the new persistent because it sets the sender as deadLetters which is not correct
                    var persistent =
                        new Persistent(
                            deserialized.Payload,
                            deserialized.SequenceNr,
                            PartitionKeyEscapeHelper.Unescape(deserialized.PersistenceId),
                            deserialized.Manifest,
                            deserialized.IsDeleted,
                            ActorRefs.NoSender,
                            deserialized.WriterGuid,
                            timestamp: savedEvent.UtcTicks);

                    if (_log.IsDebugEnabled && _settings.VerboseLogging)
                    {
                        _log.Debug("Recovering [{0}] for entity [{1}].", persistent, savedEvent.PartitionKey);
                    }

                    recoveryCallback(persistent);
                }
            }

            _log.Debug("Leaving method ReplayMessagesAsync");
        }