private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; Action <Func <IPersistentRepresentation, object> > resequence = (mapper) => { var i = 0; foreach (var resequencable in message.Messages) { if (resequencable is IPersistentRepresentation) { var p = resequencable as IPersistentRepresentation; _resequencer.Tell(new Desequenced(mapper(p), counter + i + 1, message.PersistentActor, p.Sender)); } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); } i++; } }; /* * Self MUST BE CLOSED OVER here, or the code below will be subject to race conditions which may result * in failure, as the `IActorContext` needed for resolving Context.Self will be done outside the current * execution context. */ var self = Self; WriteMessagesAsync(CreatePersistentBatch(message.Messages)).ContinueWith(t => { if (!t.IsFaulted) { _resequencer.Tell(new Desequenced(WriteMessagesSuccessful.Instance, counter, message.PersistentActor, self)); resequence(x => new WriteMessageSuccess(x, message.ActorInstanceId)); } else { _resequencer.Tell(new Desequenced(new WriteMessagesFailed(t.Exception), counter, message.PersistentActor, self)); resequence(x => new WriteMessageFailure(x, t.Exception, message.ActorInstanceId)); } }, _continuationOptions); var resequencablesLength = message.Messages.Count(); _resequencerCounter += resequencablesLength + 1; }
private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; Action <Func <IPersistentRepresentation, object> > resequence = (mapper) => { var i = 0; foreach (var resequencable in message.Messages) { if (resequencable is IPersistentRepresentation) { var p = resequencable as IPersistentRepresentation; _resequencer.Tell(new Desequenced(mapper(p), counter + i + 1, message.PersistentActor, p.Sender)); } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); } i++; } }; WriteMessagesAsync(CreatePersistentBatch(message.Messages)).ContinueWith(t => { if (!t.IsFaulted) { _resequencer.Tell(new Desequenced(WriteMessagesSuccessull.Instance, counter, message.PersistentActor, Self)); resequence(x => new WriteMessageSuccess(x, message.ActorInstanceId)); } else { _resequencer.Tell(new Desequenced(new WriteMessagesFailed(t.Exception), counter, message.PersistentActor, Self)); resequence(x => new WriteMessageFailure(x, t.Exception, message.ActorInstanceId)); } }, _continuationOptions); var resequencablesLength = message.Messages.Count(); _resequencerCounter += resequencablesLength + 1; }
private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; /* * Self MUST BE CLOSED OVER here, or the code below will be subject to race conditions which may result * in failure, as the `IActorContext` needed for resolving Context.Self will be done outside the current * execution context. */ var self = Self; _resequencerCounter += message.Messages.Aggregate(1, (acc, m) => acc + m.Size); var atomicWriteCount = message.Messages.OfType<AtomicWrite>().Count(); AtomicWrite[] prepared; Task<IImmutableList<Exception>> writeResult; Exception writeMessagesAsyncException = null; try { prepared = PreparePersistentBatch(message.Messages).ToArray(); // try in case AsyncWriteMessages throws try { writeResult = _breaker.WithCircuitBreaker(() => WriteMessagesAsync(prepared)); } catch (Exception e) { writeResult = Task.FromResult((IImmutableList<Exception>) null); writeMessagesAsyncException = e; } } catch (Exception e) { // exception from PreparePersistentBatch => rejected writeResult = Task.FromResult((IImmutableList<Exception>)Enumerable.Repeat(e, atomicWriteCount).ToImmutableList()); } Action<Func<IPersistentRepresentation, Exception, object>, IImmutableList<Exception>> resequence = (mapper, results) => { var i = 0; var enumerator = results != null ? results.GetEnumerator() : null; foreach (var resequencable in message.Messages) { if (resequencable is AtomicWrite) { var aw = resequencable as AtomicWrite; Exception exception = null; if (enumerator != null) { enumerator.MoveNext(); exception = enumerator.Current; } foreach (var p in (IEnumerable<IPersistentRepresentation>)aw.Payload) { _resequencer.Tell(new Desequenced(mapper(p, exception), counter + i + 1, message.PersistentActor, p.Sender)); i++; } } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); i++; } } }; writeResult .ContinueWith(t => { if (!t.IsFaulted && !t.IsCanceled && writeMessagesAsyncException == null) { if (t.Result != null && t.Result.Count != atomicWriteCount) throw new IllegalStateException(string.Format("AsyncWriteMessages return invalid number or results. " + "Expected [{0}], but got [{1}].", atomicWriteCount, t.Result.Count)); _resequencer.Tell(new Desequenced(WriteMessagesSuccessful.Instance, counter, message.PersistentActor, self)); resequence((x, exception) => exception == null ? (object)new WriteMessageSuccess(x, message.ActorInstanceId) : new WriteMessageRejected(x, exception, message.ActorInstanceId), t.Result); } else { var exception = writeMessagesAsyncException != null ? writeMessagesAsyncException : (t.IsFaulted ? TryUnwrapException(t.Exception) : new OperationCanceledException( "WriteMessagesAsync canceled, possibly due to timing out.")); _resequencer.Tell(new Desequenced(new WriteMessagesFailed(exception), counter, message.PersistentActor, self)); resequence((x, _) => new WriteMessageFailure(x, exception, message.ActorInstanceId), null); } }, _continuationOptions); }
private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; /* * Self MUST BE CLOSED OVER here, or the code below will be subject to race conditions which may result * in failure, as the `IActorContext` needed for resolving Context.Self will be done outside the current * execution context. */ var self = Self; _resequencerCounter += message.Messages.Aggregate(1, (acc, m) => acc + m.Size); var atomicWriteCount = message.Messages.OfType <AtomicWrite>().Count(); AtomicWrite[] prepared; Task <IImmutableList <Exception> > writeResult; Exception writeMessagesAsyncException = null; try { prepared = PreparePersistentBatch(message.Messages).ToArray(); // try in case AsyncWriteMessages throws try { writeResult = _breaker.WithCircuitBreaker(() => WriteMessagesAsync(prepared)); } catch (Exception e) { writeResult = Task.FromResult((IImmutableList <Exception>)null); writeMessagesAsyncException = e; } } catch (Exception e) { // exception from PreparePersistentBatch => rejected writeResult = Task.FromResult((IImmutableList <Exception>)Enumerable.Repeat(e, atomicWriteCount).ToImmutableList()); } Action <Func <IPersistentRepresentation, Exception, object>, IImmutableList <Exception> > resequence = (mapper, results) => { var i = 0; var enumerator = results != null?results.GetEnumerator() : null; foreach (var resequencable in message.Messages) { if (resequencable is AtomicWrite) { var aw = resequencable as AtomicWrite; Exception exception = null; if (enumerator != null) { enumerator.MoveNext(); exception = enumerator.Current; } foreach (var p in (IEnumerable <IPersistentRepresentation>)aw.Payload) { _resequencer.Tell(new Desequenced(mapper(p, exception), counter + i + 1, message.PersistentActor, p.Sender)); i++; } } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); i++; } } }; writeResult .ContinueWith(t => { if (!t.IsFaulted && !t.IsCanceled && writeMessagesAsyncException == null) { if (t.Result != null && t.Result.Count != atomicWriteCount) { throw new IllegalStateException(string.Format("AsyncWriteMessages return invalid number or results. " + "Expected [{0}], but got [{1}].", atomicWriteCount, t.Result.Count)); } _resequencer.Tell(new Desequenced(WriteMessagesSuccessful.Instance, counter, message.PersistentActor, self)); resequence((x, exception) => exception == null ? (object)new WriteMessageSuccess(x, message.ActorInstanceId) : new WriteMessageRejected(x, exception, message.ActorInstanceId), t.Result); } else { var exception = writeMessagesAsyncException != null ? writeMessagesAsyncException : (t.IsFaulted ? TryUnwrapException(t.Exception) : new OperationCanceledException( "WriteMessagesAsync canceled, possibly due to timing out.")); _resequencer.Tell(new Desequenced(new WriteMessagesFailed(exception), counter, message.PersistentActor, self)); resequence((x, _) => new WriteMessageFailure(x, exception, message.ActorInstanceId), null); } }, _continuationOptions); }
private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; Action<Func<IPersistentRepresentation, object>> resequence = (mapper) => { var i = 0; foreach (var resequencable in message.Messages) { if (resequencable is IPersistentRepresentation) { var p = resequencable as IPersistentRepresentation; _resequencer.Tell(new Desequenced(mapper(p), counter + i + 1, message.PersistentActor, p.Sender)); } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); } i++; } }; WriteMessagesAsync(CreatePersistentBatch(message.Messages)).ContinueWith(t => { if (!t.IsFaulted) { _resequencer.Tell(new Desequenced(WriteMessagesSuccessull.Instance, counter, message.PersistentActor, Self)); resequence(x => new WriteMessageSuccess(x, message.ActorInstanceId)); } else { _resequencer.Tell(new Desequenced(new WriteMessagesFailed(t.Exception), counter, message.PersistentActor, Self)); resequence(x => new WriteMessageFailure(x, t.Exception, message.ActorInstanceId)); } }, _continuationOptions); var resequencablesLength = message.Messages.Count(); _resequencerCounter += resequencablesLength + 1; }
private void HandleWriteMessages(WriteMessages message) { var counter = _resequencerCounter; Action<Func<IPersistentRepresentation, object>> resequence = (mapper) => { var i = 0; foreach (var resequencable in message.Messages) { if (resequencable is IPersistentRepresentation) { var p = resequencable as IPersistentRepresentation; _resequencer.Tell(new Desequenced(mapper(p), counter + i + 1, message.PersistentActor, p.Sender)); } else { var loopMsg = new LoopMessageSuccess(resequencable.Payload, message.ActorInstanceId); _resequencer.Tell(new Desequenced(loopMsg, counter + i + 1, message.PersistentActor, resequencable.Sender)); } i++; } }; /* * Self MUST BE CLOSED OVER here, or the code below will be subject to race conditions which may result * in failure, as the `IActorContext` needed for resolving Context.Self will be done outside the current * execution context. */ var self = Self; var resequencablesLength = message.Messages.Count(); _resequencerCounter += resequencablesLength + 1; WriteMessagesAsync(CreatePersistentBatch(message.Messages).ToArray()) .ContinueWith(t => { if (!t.IsFaulted) { _resequencer.Tell(new Desequenced(WriteMessagesSuccessful.Instance, counter, message.PersistentActor, self)); resequence(x => new WriteMessageSuccess(x, message.ActorInstanceId)); } else { _resequencer.Tell(new Desequenced(new WriteMessagesFailed(t.Exception), counter, message.PersistentActor, self)); resequence(x => new WriteMessageFailure(x, t.Exception, message.ActorInstanceId)); } }, _continuationOptions); }