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(); } }); }
#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"); } }