@Override public void start() throws Exception { System.out.println("[Main] Running in " + Thread.currentThread().getName()); vertx .deployVerticle("io.vertx.example.core.verticle.worker.WorkerVerticle", new DeploymentOptions().setWorker(true)); vertx.eventBus().send( "sample.data", "hello vert.x", r -> { System.out.println("[Main] Receiving reply ' " + r.result().body() + "' in " + Thread.currentThread().getName()); } ); } }
@Test public void testDeployWorkerUsingNamedPool() throws Exception { AtomicReference<Thread> thread = new AtomicReference<>(); AtomicReference<String> deployment = new AtomicReference<>(); String poolName = "vert.x-" + TestUtils.randomAlphaString(10); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { thread.set(Thread.currentThread()); assertTrue(Context.isOnVertxThread()); assertTrue(Context.isOnWorkerThread()); assertFalse(Context.isOnEventLoopThread()); assertTrue(Thread.currentThread().getName().startsWith(poolName + "-")); context.runOnContext(v -> { vertx.undeploy(context.deploymentID()); }); } }, new DeploymentOptions().setWorker(true).setWorkerPoolName(poolName), onSuccess(deployment::set)); assertWaitUntil(() -> thread.get() != null && thread.get().getState() == Thread.State.TERMINATED); }
@Override public void resolve(String identifier, DeploymentOptions deploymentOptions, ClassLoader classLoader, Future<String> resolution) { if (failInResolve) { resolution.fail(new IOException("whatever")); } else { identifierToResolve = identifier; deploymentOptionsToResolve = deploymentOptions; // Now we change the deployment options deploymentOptions.setConfig(new JsonObject().put("wibble", "quux")); deploymentOptions.setWorker(true); deploymentOptions.setIsolationGroup(isolationGroup); resolution.complete(resolvedIdentifier); } }
/** * Create a worker verticle for the current Vert.x and return its context. * * @return the context * @throws Exception anything preventing the creation of the worker */ protected Context createWorker() throws Exception { CompletableFuture<Context> fut = new CompletableFuture<>(); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { fut.complete(context); } }, new DeploymentOptions().setWorker(true), ar -> { if (ar.failed()) { fut.completeExceptionally(ar.cause()); } }); return fut.get(); }
@Test public void testRaceConditionWithWebsocketClientWorker() throws Exception { CompletableFuture<Context> fut = new CompletableFuture<>(); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { fut.complete(context); } }, new DeploymentOptions().setWorker(true), ar -> { if (ar.failed()) { fut.completeExceptionally(ar.cause()); } }); testRaceConditionWithWebsocketClient(fut.get()); }
deploymentOptions.setConfig(conf).setWorker(worker).setHa(ha).setInstances(instances); beforeDeployingVerticle(deploymentOptions); deploy();
@Test public void testCancelTimerWhenScheduledOnWorker() throws Exception { vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { long id = vertx.setTimer(100, id_ -> { fail(); }); Thread.sleep(200); assertTrue(vertx.cancelTimer(id)); testComplete(); } }, new DeploymentOptions().setWorker(true)); await(); } }
@Test public void testWorkerVerticleException() throws Exception { Verticle workerVerticle = new AbstractVerticle() { @Override public void start() throws Exception { try { vertx.createHttpClient(createHttp2ClientOptions()); fail("HttpClient should not work with HTTP_2"); } catch(Exception ex) { assertEquals("Cannot use HttpClient with HTTP_2 in a worker", ex.getMessage()); complete(); } } }; vertx.deployVerticle(workerVerticle, new DeploymentOptions().setWorker(true)); await(); }
}, new DeploymentOptions().setWorker(true)); await();
@Test public void testUseDifferentExecutorWithSameTaskQueue() throws Exception { int count = 10; waitFor(count); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { WorkerExecutor exec = vertx.createSharedWorkerExecutor("vert.x-the-executor"); Thread startThread = Thread.currentThread(); AtomicReference<Thread> currentThread = new AtomicReference<>(); for (int i = 0;i < count;i++) { int val = i; exec.executeBlocking(fut -> { Thread current = Thread.currentThread(); assertNotSame(startThread, current); if (val == 0) { assertNull(currentThread.getAndSet(current)); } else { assertSame(current, currentThread.get()); } fut.complete(); }, true, onSuccess(v -> complete())); } } }, new DeploymentOptions().setWorker(true), onSuccess(id -> {})); await(); }
@Test public void testWorkerExecuteFromIo() throws Exception { AtomicReference<ContextInternal> workerContext = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { workerContext.set((ContextInternal) context); latch.countDown(); } }, new DeploymentOptions().setWorker(true)); awaitLatch(latch); workerContext.get().nettyEventLoop().execute(() -> { assertNull(Vertx.currentContext()); workerContext.get().nettyEventLoop().execute(() -> { workerContext.get().executeFromIO(v -> { assertSame(workerContext.get(), Vertx.currentContext()); assertTrue(Context.isOnWorkerThread()); testComplete(); }); }); }); await(); }
@Test public void testDeployWorkerFromTestThread() throws Exception { MyVerticle verticle = new MyVerticle(); vertx.deployVerticle(verticle, new DeploymentOptions().setWorker(true), ar -> { assertDeployment(1, verticle, null, ar); assertTrue(verticle.startContext.isWorkerContext()); vertx.undeploy(ar.result(), ar2 -> { assertTrue(ar2.succeeded()); assertEquals(verticle.startContext, verticle.stopContext); testComplete(); }); }); await(); }
@Test public void testReplyFromWorker() throws Exception { String expectedBody = TestUtils.randomAlphaString(20); startNodes(2); CountDownLatch latch = new CountDownLatch(1); vertices[0].deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { vertices[1].eventBus().<String>consumer(ADDRESS1, msg -> { msg.reply(expectedBody); }).completionHandler(ar -> { assertTrue(ar.succeeded()); latch.countDown(); }); } }, new DeploymentOptions().setWorker(true)); awaitLatch(latch); vertices[0].eventBus().send(ADDRESS1, "whatever", reply -> { assertTrue(reply.succeeded()); assertEquals(expectedBody, reply.result().body()); testComplete(); }); await(); }
verticleContext.set(Vertx.currentContext()); }, new DeploymentOptions().setWorker(worker), ar1 -> { assertTrue(ar1.succeeded()); vertx.undeploy(ar1.result(), ar2 -> {
@Test public void testDeployWorkerWithConfig() throws Exception { MyVerticle verticle = new MyVerticle(); JsonObject conf = generateJSONObject(); vertx.deployVerticle(verticle, new DeploymentOptions().setConfig(conf).setWorker(true), ar -> { assertDeployment(1, verticle, conf, ar); assertTrue(verticle.startContext.isWorkerContext()); assertFalse(verticle.startContext.isEventLoopContext()); vertx.undeploy(ar.result(), ar2 -> { assertTrue(ar2.succeeded()); assertEquals(verticle.startContext, verticle.stopContext); testComplete(); }); }); await(); }
@Test public void testWorkerClient() throws Exception { String expected = TestUtils.randomAlphaString(2000); server.connectHandler(so -> { so.write(expected).close(); }); startServer(); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { NetClient client = vertx.createNetClient(); client.connect(testAddress, onSuccess(so ->{ Buffer received = Buffer.buffer(); so.handler(received::appendBuffer); so.closeHandler(v -> { assertEquals(expected, received.toString()); testComplete(); }); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } })); } }, new DeploymentOptions().setWorker(true)); await(); }
@Test public void testWorkerServer() throws Exception { String expected = TestUtils.randomAlphaString(2000); vertx.deployVerticle(new AbstractVerticle() { @Override public void start(Future<Void> startFuture) throws Exception { NetServer server = vertx.createNetServer(); server.connectHandler(so -> { Buffer received = Buffer.buffer(); so.handler(received::appendBuffer); so.closeHandler(v -> { assertEquals(expected, received.toString()); testComplete(); }); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); server.listen(testAddress, ar -> startFuture.handle(ar.mapEmpty())); } }, new DeploymentOptions().setWorker(true), onSuccess(v -> { client.connect(testAddress, onSuccess(so -> { so.write(expected).close(); })); })); await(); }
@Test public void testBlockCheckWorker() throws Exception { Verticle verticle = new AbstractVerticle() { @Override public void start() throws InterruptedException { Thread.sleep(3000); testComplete(); } }; // set warning threshold to 1s and the exception threshold as well long maxWorkerExecuteTime = 1; TimeUnit maxWorkerExecuteTimeUnit = SECONDS; VertxOptions vertxOptions = new VertxOptions(); vertxOptions.setMaxWorkerExecuteTime(maxWorkerExecuteTime); vertxOptions.setMaxWorkerExecuteTimeUnit(maxWorkerExecuteTimeUnit); vertxOptions.setWarningExceptionTime(maxWorkerExecuteTime); vertxOptions.setWarningExceptionTimeUnit(maxWorkerExecuteTimeUnit); Vertx newVertx = vertx(vertxOptions); DeploymentOptions deploymentOptions = new DeploymentOptions(); deploymentOptions.setWorker(true); newVertx.deployVerticle(verticle, deploymentOptions); await(); blockedThreadWarning.expectMessage("vert.x-worker-thread", maxWorkerExecuteTime, maxWorkerExecuteTimeUnit); }
vertx.registerVerticleFactory(factResolve); JsonObject config = new JsonObject().put("foo", "bar"); DeploymentOptions original = new DeploymentOptions().setWorker(false).setConfig(config).setIsolationGroup("somegroup"); DeploymentOptions options = new DeploymentOptions(original); vertx.deployVerticle("resolve:someid", options, res -> {
@Test public void testWorkerRightThread() throws Exception { assertFalse(Context.isOnVertxThread()); Verticle verticle = new AbstractVerticle() { @Override public void start() throws Exception { assertTrue(Context.isOnVertxThread()); assertTrue(Context.isOnWorkerThread()); assertFalse(Context.isOnEventLoopThread()); } @Override public void stop() throws Exception { assertTrue(Context.isOnVertxThread()); assertTrue(Context.isOnWorkerThread()); assertFalse(Context.isOnEventLoopThread()); } }; vertx.deployVerticle(verticle, new DeploymentOptions().setWorker(true), onSuccess(res -> { assertTrue(Context.isOnVertxThread()); assertFalse(Context.isOnWorkerThread()); assertTrue(Context.isOnEventLoopThread()); vertx.undeploy(res, onSuccess(res2 -> { assertTrue(Context.isOnVertxThread()); assertFalse(Context.isOnWorkerThread()); assertTrue(Context.isOnEventLoopThread()); testComplete(); })); })); await(); }