예제 #1
0
            public PersistenceIdsLogic(ConnectionMultiplexer redis, int database, ExtendedActorSystem system, Outlet <string> outlet, Shape shape) : base(shape)
            {
                _redis         = redis;
                _database      = database;
                _journalHelper = new JournalHelper(system, system.Settings.Config.GetString("akka.persistence.journal.redis.key-prefix"));
                _outlet        = outlet;

                SetHandler(outlet, onPull: () =>
                {
                    _downstreamWaiting = true;
                    if (_buffer.Count == 0 && (_start || _index > 0))
                    {
                        var callback = GetAsyncCallback <IEnumerable <RedisValue> >(data =>
                        {
                            // save the index for further initialization if needed
                            _index = data.AsInstanceOf <IScanningCursor>().Cursor;

                            // it is not the start anymore
                            _start = false;

                            // enqueue received data
                            try
                            {
                                foreach (var item in data)
                                {
                                    _buffer.Enqueue(item);
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e, "Error while querying persistence identifiers");
                                FailStage(e);
                            }

                            // deliver element
                            Deliver();
                        });

                        callback(_redis.GetDatabase(_database).SetScan(_journalHelper.GetIdentifiersKey(), cursor: _index));
                    }
                    else if (_buffer.Count == 0)
                    {
                        // wait for asynchornous notification and mark dowstream
                        // as waiting for data
                    }
                    else
                    {
                        Deliver();
                    }
                });
            }
            public CurrentPersistenceIdsLogic(IDatabase redisDatabase, ExtendedActorSystem system, Outlet <string> outlet, Shape shape) : base(shape)
            {
                _outlet        = outlet;
                _journalHelper = new JournalHelper(system, system.Settings.Config.GetString("akka.persistence.journal.redis.key-prefix"));

                SetHandler(outlet, onPull: () =>
                {
                    if (_buffer.Count == 0 && (_start || _index > 0))
                    {
                        var callback = GetAsyncCallback <IEnumerable <RedisValue> >(data =>
                        {
                            // save the index for further initialization if needed
                            _index = data.AsInstanceOf <IScanningCursor>().Cursor;

                            // it is not the start anymore
                            _start = false;

                            // enqueue received data
                            try
                            {
                                foreach (var item in data)
                                {
                                    _buffer.Enqueue(item);
                                }
                            }
                            catch (Exception e)
                            {
                                Log.Error(e, "Error while querying persistence identifiers");
                                FailStage(e);
                            }

                            // deliver element
                            Deliver();
                        });

                        callback(redisDatabase.SetScan(_journalHelper.GetIdentifiersKey(), cursor: _index));
                    }
                    else
                    {
                        Deliver();
                    }
                });
            }
예제 #3
0
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        private async Task WriteBatchAsync(AtomicWrite aw)
        {
            var transaction = Database.CreateTransaction();

            var payloads = aw.Payload.AsInstanceOf <IImmutableList <IPersistentRepresentation> >();

            foreach (var payload in payloads)
            {
                var(bytes, tags) = Extract(payload);

                // save the payload
                transaction.SortedSetAddAsync(_journalHelper.GetJournalKey(payload.PersistenceId), bytes, payload.SequenceNr);

                // notify about a new event being appended for this persistence id
                transaction.PublishAsync(_journalHelper.GetJournalChannel(payload.PersistenceId), payload.SequenceNr);

                // save tags
                foreach (var tag in tags)
                {
                    transaction.ListRightPushAsync(_journalHelper.GetTagKey(tag), $"{payload.SequenceNr}:{payload.PersistenceId}");
                    transaction.PublishAsync(_journalHelper.GetTagsChannel(), tag);
                }
            }

            // set highest sequence number key
            transaction.StringSetAsync(_journalHelper.GetHighestSequenceNrKey(aw.PersistenceId), aw.HighestSequenceNr);

            // add persistenceId
            transaction.SetAddAsync(_journalHelper.GetIdentifiersKey(), aw.PersistenceId).ContinueWith(task =>
            {
                if (task.Result)
                {
                    // notify about a new persistenceId
                    Database.Publish(_journalHelper.GetIdentifiersChannel(), aw.PersistenceId);
                }
            });

            if (!await transaction.ExecuteAsync())
            {
                throw new Exception($"{nameof(WriteMessagesAsync)}: failed to write {typeof(IPersistentRepresentation).Name} to redis");
            }
        }