@Suspendable @Override public void start() throws Exception { EventBus eb = vertx.eventBus(); eb.consumer(ADDRESS).handler(msg -> msg.reply("pong")); // This runs on an event loop but the event loop is at no time blocked! for (int i = 0; i < 10; i++) { System.out.println("Thread is " + Thread.currentThread()); Message<String> reply = awaitResult(h -> eb.send(ADDRESS, "ping", h)); System.out.println("got reply: " + reply.body()); // Like Thread.sleep but doesn't block the OS thread Strand.sleep(1000); } }
@Override public void await(long timeInMilliseconds) throws InterruptedException { if(timeInMilliseconds > 0){ try { Strand.sleep(timeInMilliseconds); } catch (SuspendExecution e) { // this is not a real exception // leave this method without instrumentation should be fine } } }
@Override public Void execute(final long nanoTime, final Q request) throws SuspendExecution, InterruptedException { Strand.sleep(sleepMillis, sleepNanos); return null; } }
/** * Causes the currently executing strand to sleep (temporarily cease * execution) for the specified duration, subject to * the precision and accuracy of system timers and schedulers. * * @param duration the length of time to sleep in the time unit specified by {@code unit}. * @param unit the time unit of {@code duration}. * @throws InterruptedException if any strand has interrupted the current strand. The * <i>interrupted status</i> of the current strand is * cleared when this exception is thrown. */ public static void sleep(long duration, TimeUnit unit) throws InterruptedException { try { Strand.sleep(duration, unit); } catch (SuspendExecution e) { throw RuntimeSuspendExecution.of(e); } }
/** * Causes the currently executing strand to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. * * @param millis the length of time to sleep in milliseconds * @throws IllegalArgumentException if the value of {@code millis} is negative * @throws InterruptedException if any strand has interrupted the current strand. The * <i>interrupted status</i> of the current strand is * cleared when this exception is thrown. */ public static void sleep(long millis) throws InterruptedException { try { Strand.sleep(millis); } catch (SuspendExecution e) { throw RuntimeSuspendExecution.of(e); } }
/** * Causes the currently executing strand to sleep (temporarily cease * execution) for the specified number of milliseconds plus the specified * number of nanoseconds, subject to the precision and accuracy of system * timers and schedulers. * * @param millis the length of time to sleep in milliseconds * @param nanos {@code 0-999999} additional nanoseconds to sleep * @throws IllegalArgumentException if the value of {@code millis} is negative, * or the value of {@code nanos} is not in the range {@code 0-999999} * @throws InterruptedException if any strand has interrupted the current strand. The * <i>interrupted status</i> of the current strand is * cleared when this exception is thrown. */ public static void sleep(long millis, int nanos) throws InterruptedException { try { Strand.sleep(millis, nanos); } catch (SuspendExecution e) { throw RuntimeSuspendExecution.of(e); } }
@Suspendable private void sleep(long millis) { try { Strand.sleep(millis); } catch (SuspendExecution | InterruptedException suspendExecution) { throw new AssertionError(); // Required to compile, but the try-catch block is reworked by the Quasar instrumentation } }
@Suspendable private void sleep(long millis) { try { Strand.sleep(millis); } catch (SuspendExecution | InterruptedException suspendExecution) { throw new AssertionError(); // Required to compile, but the try-catch block is reworked by the Quasar instrumentation } }
private static class RequestExecOutcome<Res> { final long execTime; final Res response; final Exception exception; public RequestExecOutcome(final long execTime, final Res response, final Exception exception) { this.execTime = execTime; this.response = response; this.exception = exception; } }
private boolean onQueueFull(int iter, boolean timed, long nanos) throws SuspendExecution, InterruptedException, TimeoutException { switch (overflowPolicy) { case DROP: return false; case THROW: throw new QueueCapacityExceededException(); case BLOCK: if (timed) sendersSync.await(iter, nanos, TimeUnit.NANOSECONDS); else sendersSync.await(iter); return true; case BACKOFF: if (iter > MAX_SEND_RETRIES) throw new QueueCapacityExceededException(); if (iter > 5) Strand.sleep((iter - 5) * 5); else if (iter > 4) Strand.yield(); return true; default: throw new AssertionError("Unsupportd policy: " + overflowPolicy); } }
@Suspendable protected void testSleep() throws Exception { Thread th = Thread.currentThread(); AtomicInteger cnt = new AtomicInteger(); vertx.setPeriodic(1, tid -> { assertSame(Thread.currentThread(), th); cnt.incrementAndGet(); }); assertSame(Thread.currentThread(), th); Strand.sleep(1000, TimeUnit.MILLISECONDS); assertSame(Thread.currentThread(), th); assertTrue(cnt.get() > 900); complete(); }
@Suspendable protected void testSleep() throws Exception { Thread th = Thread.currentThread(); AtomicInteger cnt = new AtomicInteger(); vertx.setPeriodic(1, tid -> { assertSame(Thread.currentThread(), th); cnt.incrementAndGet(); }); assertSame(Thread.currentThread(), th); Strand.sleep(1000, TimeUnit.MILLISECONDS); assertSame(Thread.currentThread(), th); assertTrue(cnt.get() > 900); complete(); }