@Test public void testNoStackOverflowErrorWithImmediateEventExecutorB() throws Exception { final Promise<Void>[] p = new DefaultPromise[128]; for (int i = 0; i < p.length; i++) { final int finalI = i; p[i] = new DefaultPromise<Void>(ImmediateEventExecutor.INSTANCE); p[i].addListener( new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { DefaultPromise.notifyListener( ImmediateEventExecutor.INSTANCE, future, new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { if (finalI + 1 < p.length) { p[finalI + 1].setSuccess(null); } } }); } }); } p[0].setSuccess(null); for (Promise<Void> a : p) { assertThat(a.isSuccess(), is(true)); } }
@Test(expected = CancellationException.class) public void testCancellationExceptionIsThrownWhenBlockingGetWithTimeout() throws InterruptedException, ExecutionException, TimeoutException { final Promise<Void> promise = new DefaultPromise<Void>(ImmediateEventExecutor.INSTANCE); promise.cancel(false); promise.get(1, TimeUnit.SECONDS); }
@Override public SEXP apply(Context context, Environment rho, FunctionCall call, PairList args) { PairList matchedArguments = ClosureDispatcher.matchArguments(formals, args); SEXP exprArgument = matchedArguments.findByTag(EXPR_ARGUMENT); SEXP envArgument = matchedArguments.findByTag(ENV_ARGUMENT); // Substitute handles ... in an idiosyncratic way: // Only the first argument is used, and there is no attempt to // match subsequent arguments against the 'env' argument. SEXP expr; if (exprArgument == Symbols.ELLIPSES) { SEXP ellipses = rho.getVariable(Symbols.ELLIPSES); if (ellipses == Null.INSTANCE) { expr = Null.INSTANCE; } else { PromisePairList.Node promisePairList = (PromisePairList.Node) ellipses; Promise promisedArg = (Promise) promisePairList.getValue(); expr = promisedArg.getExpression(); } } else { expr = exprArgument; } return substitute(expr, buildContext(context, rho, envArgument)); }
@Test public void testListenerNotifyOrder() throws Exception { EventExecutor executor = new TestEventExecutor(); try { final BlockingQueue<FutureListener<Void>> listeners = new LinkedBlockingQueue<FutureListener<Void>>(); int runs = 100000; for (int i = 0; i < runs; i++) { final Promise<Void> promise = new DefaultPromise<Void>(executor); final FutureListener<Void> listener1 = new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { listeners.add(this); } }; final FutureListener<Void> listener2 = new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { listeners.add(this); } }; final FutureListener<Void> listener4 = new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { listeners.add(this); } }; final FutureListener<Void> listener3 = new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { listeners.add(this); future.addListener(listener4); } }; GlobalEventExecutor.INSTANCE.execute( new Runnable() { @Override public void run() { promise.setSuccess(null); } }); promise.addListener(listener1).addListener(listener2).addListener(listener3); assertSame("Fail 1 during run " + i + " / " + runs, listener1, listeners.take()); assertSame("Fail 2 during run " + i + " / " + runs, listener2, listeners.take()); assertSame("Fail 3 during run " + i + " / " + runs, listener3, listeners.take()); assertSame("Fail 4 during run " + i + " / " + runs, listener4, listeners.take()); assertTrue("Fail during run " + i + " / " + runs, listeners.isEmpty()); } } finally { executor.shutdownGracefully(0, 0, TimeUnit.SECONDS).sync(); } }
protected void forwardToCoord(long seqno, Message msg) { if (is_coord) { forward(msg, seqno, false); return; } if (!running || flushing) { forward_table.put(seqno, msg); return; } if (!ack_mode) { forward_table.put(seqno, msg); forward(msg, seqno, false); return; } send_lock.lock(); try { forward_table.put(seqno, msg); while (running && !flushing) { ack_promise.reset(); forward(msg, seqno, true); if (!ack_mode || !running || flushing) break; Long ack = ack_promise.getResult(500); if ((Objects.equals(ack, seqno)) || !forward_table.containsKey(seqno)) break; } } finally { send_lock.unlock(); } }
public List<PingData> get(long timeout) throws InterruptedException { long start_time = System.currentTimeMillis(), time_to_wait = timeout; promise.getLock().lock(); try { while (time_to_wait > 0 && !promise.hasResult()) { // if num_expected_srv_rsps > 0, then it overrides num_expected_rsps if (num_expected_srv_rsps > 0) { int received_srv_rsps = getNumServerResponses(ping_rsps); if (received_srv_rsps >= num_expected_srv_rsps) return new LinkedList<PingData>(ping_rsps); } else if (ping_rsps.size() >= num_expected_rsps) { return new LinkedList<PingData>(ping_rsps); } if (break_on_coord_rsp && containsCoordinatorResponse(ping_rsps)) return new LinkedList<PingData>(ping_rsps); promise.getCond().await(time_to_wait, TimeUnit.MILLISECONDS); time_to_wait = timeout - (System.currentTimeMillis() - start_time); } return new LinkedList<PingData>(ping_rsps); } finally { promise.getLock().unlock(); } }
public OrPromise(Promise<?>... values) { this.values = values; Runnable callback = new OrPromiseCallback(); for (Promise<?> value : values) { if (value != null) { value.addCallback(callback); } else { callback.run(); } } }
@Override protected void onPostExecute(RecipeEntity result) { if (delegate == null) { throw new IllegalStateException("Delegate should be initialized for the task to execute."); } if (mError == null) { delegate.resolve(result); } else { delegate.reject(mError); } }
protected void deliver(Message msg, Event evt, SequencerHeader hdr) { Address sender = msg.getSrc(); if (sender == null) { if (log.isErrorEnabled()) log.error(local_addr + ": sender is null, cannot deliver " + "::" + hdr.getSeqno()); return; } long msg_seqno = hdr.getSeqno(); if (sender.equals(local_addr)) { forward_table.remove(msg_seqno); if (hdr.flush_ack) { ack_promise.setResult(msg_seqno); if (ack_mode && !flushing && threshold > 0 && ++num_acks >= threshold) { ack_mode = false; num_acks = 0; } } } if (!canDeliver(sender, msg_seqno)) { if (log.isWarnEnabled()) log.warn(local_addr + ": dropped duplicate message " + sender + "::" + msg_seqno); return; } if (log.isTraceEnabled()) log.trace(local_addr + ": delivering " + sender + "::" + msg_seqno); up_prot.up(evt); delivered_bcasts++; }
public AsyncFlow<R> recover(final IAction<Exception, R> action) { final Promise<R> resultPromise = new Promise<R>(); promise.onDelivered( new Callback<R>() { public void onResult(R result) { resultPromise.deliver(result); } public void onFailure(Exception e) { R result; try { result = action.doAction(e); } catch (Exception e1) { resultPromise.deliverException(e1); return; } resultPromise.deliver(result); } }); return new AsyncFlow<R>(resultPromise); }
public <R1> AsyncFlow<R1> then(final IAsyncAction<R, R1> action) { final Promise<R1> resultPromise = new Promise<R1>(); promise.onDelivered( new Callback<R>() { public void onResult(R result) { Promise<R1> newPromise = action.doAction(result); newPromise.onDelivered( new Callback<R1>() { public void onResult(R1 result) { resultPromise.deliver(result); } public void onFailure(Exception e) { resultPromise.deliverException(e); } }); } public void onFailure(Exception e) { resultPromise.deliverException(e); } }); return new AsyncFlow<R1>(resultPromise); }
public AsyncFlow<R> returnInExecutor(final Executor executor) { final Promise<R> resultPromise = new Promise<R>(); promise.onDelivered( new Callback<R>() { @Override public void onResult(final R result) { executor.execute( new Runnable() { @Override public void run() { resultPromise.deliver(result); } }); } @Override public void onFailure(final Exception e) { executor.execute( new Runnable() { @Override public void run() { resultPromise.deliverException(e); } }); } }); return new AsyncFlow<R>(resultPromise); }
public static Promise<Result> get(String symbol) { ActorRef stockSentimentActor = ActorManagerExtension.ActorManagerExtensionProvider.get(Akka.system()) .getStockSentimentProxy(); Future<Object> futureStockSentiments = Patterns.ask(stockSentimentActor, new StockSentimentActor.GetSentiment(symbol), timeout); Promise<Object> promiseSentiments = Promise.wrap(futureStockSentiments); return promiseSentiments .<Result>map( obj -> { StockSentimentActor.SendSentiment sendSentiment = (StockSentimentActor.SendSentiment) obj; return Results.ok(sendSentiment.getSentiment()); }) .recover(StockSentiment::errorResponse); }
protected void getState(Address target, long timeout, Callable<Boolean> flushInvoker) throws Exception { checkClosedOrNotConnected(); if (!state_transfer_supported) throw new IllegalStateException( "fetching state will fail as state transfer is not supported. " + "Add one of the state transfer protocols to your configuration"); if (target == null) target = determineCoordinator(); if (target != null && local_addr != null && target.equals(local_addr)) { log.trace( local_addr + ": cannot get state from myself (" + target + "): probably the first member"); return; } boolean initiateFlush = flushSupported() && flushInvoker != null; if (initiateFlush) { boolean successfulFlush = false; try { successfulFlush = flushInvoker.call(); } catch (Throwable e) { successfulFlush = false; // http://jira.jboss.com/jira/browse/JGRP-759 } if (!successfulFlush) throw new IllegalStateException( "Node " + local_addr + " could not flush the cluster for state retrieval"); } state_promise.reset(); StateTransferInfo state_info = new StateTransferInfo(target, timeout); long start = System.currentTimeMillis(); down(new Event(Event.GET_STATE, state_info)); StateTransferResult result = state_promise.getResult(state_info.timeout); if (initiateFlush) stopFlush(); if (result == null) throw new StateTransferException( "timeout during state transfer (" + (System.currentTimeMillis() - start) + "ms)"); if (result.hasException()) throw new StateTransferException("state transfer failed", result.getException()); }
/** * Zips the values of this promise with <code>another</code>, and creates a new promise holding * the tuple of their results * * @param another */ public <B> Promise<Tuple<A, B>> zip(Promise<B> another) { return wrap(wrapped().zip(another.wrapped())) .map( new Function<scala.Tuple2<A, B>, Tuple<A, B>>() { public Tuple<A, B> apply(scala.Tuple2<A, B> scalaTuple) { return new Tuple(scalaTuple._1, scalaTuple._2); } }); }
public JiraTickets tickets() throws ExecutionException, InterruptedException { List<JiraTicket> jiraTickets = new ArrayList<JiraTicket>(); for (BasicIssue issuesKey : issuesKeys) { Promise<Issue> issuePromise = issueRestClient.getIssue(issuesKey.getKey()); Issue i = issuePromise.get(); JiraTicket ticket = new JiraTicket( i.getKey(), field(i, HOTFIX_TO), field(i, FIX_DETAILS), field(i, HOTFIX_FILES), field(i, HOTFIX_INSTRUCTIONS), field(i, HOTFIX_APPROVED_BY), field(i, VERIFICATION_DETAILS)); jiraTickets.add(ticket); } return new JiraTickets(jiraTickets); }
public void uploadAttachments(JiraTickets tickets) throws ExecutionException, InterruptedException, IOException { for (JiraTicket t : tickets) { Promise<Issue> issuePromise = issueRestClient.getIssue(t.getId()); Issue i = issuePromise.get(); File rollback = t.getRollback(); File hotfix = t.getHotfix(); if (rollback != null && rollback.canRead()) { issueRestClient.addAttachment( i.getAttachmentsUri(), FileUtils.openInputStream(rollback), rollback.getName()); } if (hotfix != null && hotfix.canRead()) { issueRestClient.addAttachment( i.getAttachmentsUri(), FileUtils.openInputStream(hotfix), hotfix.getName()); } } }
protected void unblockAll() { flushing = false; send_lock.lock(); try { send_cond.signalAll(); ack_promise.setResult(null); } finally { send_lock.unlock(); } }
public static void main(String[] args) { System.out.println("*** Simple test"); { ArrayList<String> out = new ArrayList<>(); StreamSink<String> sa = new StreamSink<>(); Promise<String> pa = new Promise<>(sa); StreamSink<String> sb = new StreamSink<>(); Promise<String> pb = new Promise<>(sb); Promise<String> p = Promise.lift((a, b) -> a + " " + b, pa, pb); sa.send("Hello"); p.thenDo(t -> System.out.println(t)); sb.send("World"); } System.out.println("*** Simultaneous case"); { ArrayList<String> out = new ArrayList<>(); StreamSink<String> sa = new StreamSink<>(); Promise<String> pa = new Promise<>(sa); StreamSink<String> sb = new StreamSink<>(); Promise<String> pb = new Promise<>(sb); Promise<String> p = Promise.lift((a, b) -> a + " " + b, pa, pb); p.thenDo(t -> System.out.println(t)); Transaction.runVoid( () -> { sa.send("Hello"); sb.send("World"); }); } }
protected void stopFlusher() { flushing = false; Thread tmp = flusher; while (tmp != null && tmp.isAlive()) { tmp.interrupt(); ack_promise.setResult(null); try { tmp.join(); } catch (InterruptedException e) { } } }
public void updateTickets(JiraTickets tickets) throws ExecutionException, InterruptedException { for (JiraTicket t : tickets) { Promise<Issue> issuePromise = issueRestClient.getIssue(t.getId()); Issue i = issuePromise.get(); // find transition (we need ID) Iterable<Transition> transitions = issueRestClient.getTransitions(i.getTransitionsUri()).get(); String tName = "Hotfix Failed"; if (t.isValid()) { tName = "Out On Dev"; } Transition transition = find(transitions, tName); if (transition == null) { continue; } // prepare fields // List<FieldInput> fields = Arrays.asList( new FieldInput("resolution", // ComplexIssueInputFieldValue.with("name", "RerunPass"))); Comment comment = Comment.valueOf(StringUtils.join(t.getValidationMessages(), "\n")); issueRestClient.transition(i, new TransitionInput(transition.getId(), comment)); } }
public void sendDiscoveryRequest(String cluster_name, Promise promise, ViewId view_id) throws Exception { PingData data = null; PhysicalAddress physical_addr = (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); if (view_id == null) { List<PhysicalAddress> physical_addrs = Arrays.asList(physical_addr); data = new PingData(local_addr, null, false, UUID.get(local_addr), physical_addrs); } PingHeader hdr = new PingHeader(PingHeader.GET_MBRS_REQ, data, cluster_name); hdr.view_id = view_id; Collection<PhysicalAddress> cluster_members = fetchClusterMembers(cluster_name); if (cluster_members == null) { Message msg = new Message(null); // multicast msg msg.setFlag(Message.OOB); msg.putHeader(getId(), hdr); sendMcastDiscoveryRequest(msg); } else { if (cluster_members.isEmpty()) { // if we don't find any members, return immediately if (promise != null) promise.setResult(null); } else { for (final Address addr : cluster_members) { if (addr.equals(physical_addr)) // no need to send the request to myself continue; final Message msg = new Message(addr, null, null); msg.setFlag(Message.OOB); msg.putHeader(this.id, hdr); if (log.isTraceEnabled()) log.trace("[FIND_INITIAL_MBRS] sending discovery request to " + msg.getDest()); if (!sendDiscoveryRequestsInParallel()) { down_prot.down(new Event(Event.MSG, msg)); } else { timer.execute( new Runnable() { public void run() { try { down_prot.down(new Event(Event.MSG, msg)); } catch (Exception ex) { if (log.isErrorEnabled()) log.error("failed sending discovery request to " + addr + ": " + ex); } } }); } } } } }
private static void testPromiseListenerAddWhenComplete(Throwable cause) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final Promise<Void> promise = new DefaultPromise<Void>(ImmediateEventExecutor.INSTANCE); promise.addListener( new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { promise.addListener( new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { latch.countDown(); } }); } }); if (cause == null) { promise.setSuccess(null); } else { promise.setFailure(cause); } latch.await(); }
public void addResponse(PingData rsp, boolean overwrite) { if (rsp == null) return; promise.getLock().lock(); try { if (overwrite) ping_rsps.remove(rsp); // https://jira.jboss.org/jira/browse/JGRP-1179 int index = ping_rsps.indexOf(rsp); if (index == -1) { ping_rsps.add(rsp); promise.getCond().signalAll(); } else if (rsp.isCoord()) { PingData pr = ping_rsps.get(index); // Check if the already existing element is not server if (!pr.isCoord()) { ping_rsps.set(index, rsp); promise.getCond().signalAll(); } } } finally { promise.getLock().unlock(); } }
public <F extends ListenableFuture<? extends I>> F track(final F job) { startedCount.incrementAndGet(); if (!isAcceptingNewJobs()) job.cancel(completionPromise.wasCancelledWithInterruption()); job.addListener( () -> { try { handleCompletedJob(job); } catch (Exception e) { abort(FunFuture.unwrapExecutionException(e)); } finally { completedCount.incrementAndGet(); checkDone(); } }, jobCompletionExecutor); return job; }
public <Any> AsyncFlow<Any> inParallelWithNext(final IAsyncAction<R, Any> action) { final Promise<Any> resultPromise = new Promise<Any>(); promise.onDelivered( new Callback<R>() { @SuppressWarnings("unused") public void onResult(R result) { Promise<Any> newPromise = action.doAction(result); resultPromise.deliver(); // force running rest chain before the action completed } public void onFailure(Exception e) { resultPromise.deliverException(e); } }); return new AsyncFlow<Any>(resultPromise); }
@Override public void add(final AsyncContextBase async, Promise<?> waitFor) { checkClosed(); heirs.add(async); if (!async.isDaemon()) { nonDaemonHeirsCount++; } if (waitFor == null) { executor.execute(async); } else { waitFor.addCallback( new Runnable() { @Override public void run() { executor.execute(async); } }); } }
/** * Sends all messages currently in forward_table to the new coordinator (changing the dest field). * This needs to be done, so the underlying reliable unicast protocol (e.g. UNICAST) adds these * messages to its retransmission mechanism<br> * Note that we need to resend the messages in order of their seqnos ! We also need to prevent * other message from being inserted until we're done, that's why there's synchronization.<br> * Access to the forward_table doesn't need to be synchronized as there won't be any insertions * during flushing (all down-threads are blocked) */ protected void flushMessagesInForwardTable() { if (is_coord) { for (Map.Entry<Long, Message> entry : forward_table.entrySet()) { Long key = entry.getKey(); Message msg = entry.getValue(); Buffer buf; try { buf = Util.streamableToBuffer(msg); } catch (Exception e) { log.error(Util.getMessage("FlushingBroadcastingFailed"), e); continue; } SequencerHeader hdr = new SequencerHeader(SequencerHeader.WRAPPED_BCAST, key); Message forward_msg = new Message(null, buf).putHeader(this.id, hdr); if (log.isTraceEnabled()) log.trace(local_addr + ": flushing (broadcasting) " + local_addr + "::" + key); down_prot.down(new Event(Event.MSG, forward_msg)); } return; } // for forwarded messages, we need to receive the forwarded message from the coordinator, to // prevent this case: // - V1={A,B,C} // - A crashes // - C installs V2={B,C} // - C forwards messages 3 and 4 to B (the new coord) // - B drops 3 because its view is still V1 // - B installs V2 // - B receives message 4 and broadcasts it // ==> C's message 4 is delivered *before* message 3 ! // ==> By resending 3 until it is received, then resending 4 until it is received, we make sure // this won't happen // (see https://issues.jboss.org/browse/JGRP-1449) while (flushing && running && !forward_table.isEmpty()) { Map.Entry<Long, Message> entry = forward_table.firstEntry(); final Long key = entry.getKey(); Message msg = entry.getValue(); Buffer buf; try { buf = Util.streamableToBuffer(msg); } catch (Exception e) { log.error(Util.getMessage("FlushingBroadcastingFailed"), e); continue; } while (flushing && running && !forward_table.isEmpty()) { SequencerHeader hdr = new SequencerHeader(SequencerHeader.FLUSH, key); Message forward_msg = new Message(coord, buf).putHeader(this.id, hdr).setFlag(Message.Flag.DONT_BUNDLE); if (log.isTraceEnabled()) log.trace( local_addr + ": flushing (forwarding) " + local_addr + "::" + key + " to coord " + coord); ack_promise.reset(); down_prot.down(new Event(Event.MSG, forward_msg)); Long ack = ack_promise.getResult(500); if ((Objects.equals(ack, key)) || !forward_table.containsKey(key)) break; } } }
/** * Copies the value or error from the source promise to the destination promise. * * @param source the source promise * @param dest the destination promise * @param <T> the value type for both promises */ public static <T, S extends T> void propagateResult( final Promise<S> source, final SettablePromise<? super T> dest) { source.addListener(new PropagateResultListener<T, S>(source, dest)); }
/** User: josh Date: 6/30/14 Time: 11:52 AM */ public abstract class AbstractCompletionTracker<I, O> { private final Executor jobCompletionExecutor; private final Promise<O> completionPromise = Promise.newPromise(); private final AtomicLong startedCount = new AtomicLong(); private final AtomicLong completedCount = new AtomicLong(); private final AtomicBoolean markedComplete = new AtomicBoolean(); public AbstractCompletionTracker(Executor jobCompletionExecutor) { this.jobCompletionExecutor = jobCompletionExecutor; } protected abstract void handleCompletedJob(ListenableFuture<? extends I> job) throws Exception; protected abstract O computeResult() throws Exception; public FunFuture<O> getCompletionFuture() { return completionPromise; } public boolean isAcceptingNewJobs() { return !isDone(); } public boolean isDone() { return completionPromise.isDone(); } public AbstractCompletionTracker<I, O> trackAll( Iterable<? extends ListenableFuture<? extends I>> futures) { for (ListenableFuture<? extends I> future : futures) { track(future); } return this; } public <F extends ListenableFuture<? extends I>> F track(final F job) { startedCount.incrementAndGet(); if (!isAcceptingNewJobs()) job.cancel(completionPromise.wasCancelledWithInterruption()); job.addListener( () -> { try { handleCompletedJob(job); } catch (Exception e) { abort(FunFuture.unwrapExecutionException(e)); } finally { completedCount.incrementAndGet(); checkDone(); } }, jobCompletionExecutor); return job; } /** * Completes the completion-future with the given exception, and causes all subsequently-submitted * jobs to be rejected/cancelled. * * @return true if this exception was applied to the completion of this tracker */ protected boolean abort(Throwable e) { return completionPromise.setFailure(e); } public long getIncompleteJobCount() { return startedCount.get() - completedCount.get(); } public long getCompletedJobCount() { return completedCount.get(); } protected void checkDone() { if (allJobsDone() && markedComplete.compareAndSet(false, true)) { completionPromise.complete(this::computeResult); } } protected boolean allJobsDone() { return getIncompleteJobCount() == 0; } }