- /**
- * This method is overridden to ensure the previous Tx's ready operations complete
- * before we create the next shard Tx in the chain to avoid creation failures if the
- * previous Tx's ready operations haven't completed yet.
- */
- @Override
- protected Future<Object> sendCreateTransaction(final ActorSelection shard,
- final Object serializedCreateMessage) {
- // Check if there are any previous ready Futures. Also make sure the previous ready
- // Futures aren't for this Tx as deadlock would occur if tried to wait on our own
- // Futures. This may happen b/c the shard Tx creates are done async so it's possible
- // for the client to ready this Tx before we've even attempted to create a shard Tx.
- if(previousTxReadyFutures == null ||
- previousTxReadyFutures.getKey().equals(getIdentifier())) {
- return super.sendCreateTransaction(shard, serializedCreateMessage);
- }
-
- // Combine the ready Futures into 1.
- Future<Iterable<ActorSelection>> combinedFutures = akka.dispatch.Futures.sequence(
- previousTxReadyFutures.getValue(), actorContext.getActorSystem().dispatcher());
-
- // Add a callback for completion of the combined Futures.
- final Promise<Object> createTxPromise = akka.dispatch.Futures.promise();
- OnComplete<Iterable<ActorSelection>> onComplete = new OnComplete<Iterable<ActorSelection>>() {
- @Override
- public void onComplete(Throwable failure, Iterable<ActorSelection> notUsed) {
- if(failure != null) {
- // A Ready Future failed so fail the returned Promise.
- createTxPromise.failure(failure);
- } else {
- // Send the CreateTx message and use the resulting Future to complete the
- // returned Promise.
- createTxPromise.completeWith(actorContext.executeOperationAsync(shard,
- serializedCreateMessage));
- }
- }
- };
-
- combinedFutures.onComplete(onComplete, actorContext.getActorSystem().dispatcher());
-
- return createTxPromise.future();
- }