All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.core.Context Maven / Gradle / Ivy

There is a newer version: 5.0.0.CR1
Show newest version
/*
 * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

package io.vertx.core;

import io.vertx.codegen.annotations.Fluent;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.Nullable;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.impl.VertxThread;
import io.vertx.core.impl.launcher.VertxCommandLauncher;
import io.vertx.core.json.JsonObject;

import java.util.List;
import java.util.concurrent.Callable;

/**
 * The execution context of a {@link io.vertx.core.Handler} execution.
 * 

* When Vert.x provides an event to a handler or calls the start or stop methods of a {@link io.vertx.core.Verticle}, * the execution is associated with a {@code Context}. *

* Usually a context is an *event-loop context* and is tied to a specific event loop thread. So executions for that * context always occur on that exact same event loop thread. *

* In the case of worker verticles and running inline blocking code a worker context will be associated with the execution * which will use a thread from the worker thread pool. *

* When a handler is set by a thread associated with a specific context, the Vert.x will guarantee that when that handler * is executed, that execution will be associated with the same context. *

* If a handler is set by a thread not associated with a context (i.e. a non Vert.x thread). Then a new context will * be created for that handler. *

* In other words, a context is propagated. *

* This means that when a verticle is deployed, any handlers it sets will be associated with the same context - the context * of the verticle. *

* This means (in the case of a standard verticle) that the verticle code will always be executed with the exact same * thread, so you don't have to worry about multi-threaded acccess to the verticle state and you can code your application * as single threaded. *

* This class also allows arbitrary data to be {@link #put} and {@link #get} on the context so it can be shared easily * amongst different handlers of, for example, a verticle instance. *

* This class also provides {@link #runOnContext} which allows an action to be executed asynchronously using the same context. * * @author Tim Fox */ @VertxGen public interface Context { /** * Is the current thread a worker thread? *

* NOTE! This is not always the same as calling {@link Context#isWorkerContext}. If you are running blocking code * from an event loop context, then this will return true but {@link Context#isWorkerContext} will return false. * * @return true if current thread is a worker thread, false otherwise */ static boolean isOnWorkerThread() { Thread t = Thread.currentThread(); return t instanceof VertxThread && ((VertxThread) t).isWorker(); } /** * Is the current thread an event thread? *

* NOTE! This is not always the same as calling {@link Context#isEventLoopContext}. If you are running blocking code * from an event loop context, then this will return false but {@link Context#isEventLoopContext} will return true. * * @return true if current thread is an event thread, false otherwise */ static boolean isOnEventLoopThread() { Thread t = Thread.currentThread(); return t instanceof VertxThread && !((VertxThread) t).isWorker(); } /** * Is the current thread a Vert.x thread? That's either a worker thread or an event loop thread * * @return true if current thread is a Vert.x thread, false otherwise */ static boolean isOnVertxThread() { return Thread.currentThread() instanceof VertxThread; } /** * Run the specified action asynchronously on the same context, some time after the current execution has completed. * * @param action the action to run */ void runOnContext(Handler action); /** * Safely execute some blocking code. *

* Executes the blocking code in the handler {@code blockingCodeHandler} using a thread from the worker pool. *

* The returned future will be completed with the result on the original context (i.e. on the original event loop of the caller) * or failed when the handler throws an exception. *

* A {@code Future} instance is passed into {@code blockingCodeHandler}. When the blocking code successfully completes, * the handler should call the {@link Promise#complete} or {@link Promise#complete(Object)} method, or the {@link Promise#fail} * method if it failed. *

* The blocking code should block for a reasonable amount of time (i.e no more than a few seconds). Long blocking operations * or polling operations (i.e a thread that spin in a loop polling events in a blocking fashion) are precluded. *

* When the blocking operation lasts more than the 10 seconds, a message will be printed on the console by the * blocked thread checker. *

* Long blocking operations should use a dedicated thread managed by the application, which can interact with * verticles using the event-bus or {@link Context#runOnContext(Handler)} * * @param blockingCodeHandler handler representing the blocking code to run * @param resultHandler handler that will be called when the blocking code is complete * @param ordered if true then if executeBlocking is called several times on the same context, the executions * for that context will be executed serially, not in parallel. if false then they will be no ordering * guarantees * @param the type of the result * @deprecated instead use {@link #executeBlocking(Callable, boolean)} */ @Deprecated void executeBlocking(Handler> blockingCodeHandler, boolean ordered, Handler> resultHandler); /** * Safely execute some blocking code. *

* Executes the blocking code in the handler {@code blockingCodeHandler} using a thread from the worker pool. *

* The returned future will be completed with the result on the original context (i.e. on the original event loop of the caller) * or failed when the handler throws an exception. *

* The blocking code should block for a reasonable amount of time (i.e no more than a few seconds). Long blocking operations * or polling operations (i.e a thread that spin in a loop polling events in a blocking fashion) are precluded. *

* When the blocking operation lasts more than the 10 seconds, a message will be printed on the console by the * blocked thread checker. *

* Long blocking operations should use a dedicated thread managed by the application, which can interact with * verticles using the event-bus or {@link Context#runOnContext(Handler)} * * @param blockingCodeHandler handler representing the blocking code to run * @param ordered if true then if executeBlocking is called several times on the same context, the executions * for that context will be executed serially, not in parallel. if false then they will be no ordering * guarantees * @param the type of the result * @return a future completed when the blocking code is complete */ @GenIgnore(GenIgnore.PERMITTED_TYPE) Future<@Nullable T> executeBlocking(Callable blockingCodeHandler, boolean ordered); /** * Like {@link #executeBlocking(Callable)} but using a callback. */ @GenIgnore(GenIgnore.PERMITTED_TYPE) default void executeBlocking(Callable blockingCodeHandler, Handler> resultHandler) { Future future = executeBlocking(blockingCodeHandler, true); if (resultHandler != null) { future.onComplete(resultHandler); } } /** * Like {@link #executeBlocking(Callable, boolean)} but using a callback. */ @GenIgnore(GenIgnore.PERMITTED_TYPE) default void executeBlocking(Callable blockingCodeHandler, boolean ordered, Handler> resultHandler) { Future future = executeBlocking(blockingCodeHandler, ordered); if (resultHandler != null) { future.onComplete(resultHandler); } } /** * Invoke {@link #executeBlocking(Handler, boolean, Handler)} with order = true. * @param blockingCodeHandler handler representing the blocking code to run * @param resultHandler handler that will be called when the blocking code is complete * @param the type of the result * @deprecated instead use {@link #executeBlocking(Callable)} */ @Deprecated default void executeBlocking(Handler> blockingCodeHandler, Handler> resultHandler) { executeBlocking(blockingCodeHandler, true, resultHandler); } /** * Same as {@link #executeBlocking(Handler, boolean, Handler)} but with an {@code handler} called when the operation completes * * @deprecated instead use {@link #executeBlocking(Callable, boolean)} */ @Deprecated Future<@Nullable T> executeBlocking(Handler> blockingCodeHandler, boolean ordered); /** * Same as {@link #executeBlocking(Handler, Handler)} but with an {@code handler} called when the operation completes * * @deprecated instead use {@link #executeBlocking(Callable)} */ @Deprecated default Future<@Nullable T> executeBlocking(Handler> blockingCodeHandler) { return executeBlocking(blockingCodeHandler, true); } /** * Invoke {@link #executeBlocking(Callable, boolean)} with order = true. * @param blockingCodeHandler handler representing the blocking code to run * @param the type of the result * @return a future completed when the blocking code is complete */ @GenIgnore(GenIgnore.PERMITTED_TYPE) default Future<@Nullable T> executeBlocking(Callable blockingCodeHandler) { return executeBlocking(blockingCodeHandler, true); } /** * If the context is associated with a Verticle deployment, this returns the deployment ID of that deployment. * * @return the deployment ID of the deployment or null if not a Verticle deployment */ String deploymentID(); /** * If the context is associated with a Verticle deployment, this returns the configuration that was specified when * the verticle was deployed. * * @return the configuration of the deployment or null if not a Verticle deployment */ @Nullable JsonObject config(); /** * The process args */ default List processArgs() { return VertxCommandLauncher.getProcessArguments(); } /** * Is the current context an event loop context? *

* NOTE! when running blocking code using {@link io.vertx.core.Vertx#executeBlocking(Callable)} from a * standard (not worker) verticle, the context will still an event loop context and this {@link this#isEventLoopContext()} * will return true. * * @return true if false otherwise */ boolean isEventLoopContext(); /** * Is the current context a worker context? *

* NOTE! when running blocking code using {@link io.vertx.core.Vertx#executeBlocking(Callable)} from a * standard (not worker) verticle, the context will still an event loop context and this {@link this#isWorkerContext()} * will return false. * * @return true if the current context is a worker context, false otherwise */ boolean isWorkerContext(); /** * @return the context threading model */ ThreadingModel threadingModel(); /** * Get some data from the context. * * @param key the key of the data * @param the type of the data * @return the data */ T get(Object key); /** * Put some data in the context. *

* This can be used to share data between different handlers that share a context * * @param key the key of the data * @param value the data */ void put(Object key, Object value); /** * Remove some data from the context. * * @param key the key to remove * @return true if removed successfully, false otherwise */ boolean remove(Object key); /** * Get some local data from the context. * * @param key the key of the data * @param the type of the data * @return the data */ T getLocal(Object key); /** * Put some local data in the context. *

* This can be used to share data between different handlers that share a context * * @param key the key of the data * @param value the data */ void putLocal(Object key, Object value); /** * Remove some local data from the context. * * @param key the key to remove * @return true if removed successfully, false otherwise */ boolean removeLocal(Object key); /** * @return The Vertx instance that created the context */ Vertx owner(); /** * @return the number of instances of the verticle that were deployed in the deployment (if any) related * to this context */ int getInstanceCount(); /** * Set an exception handler called when the context runs an action throwing an uncaught throwable.

* * When this handler is called, {@link Vertx#currentContext()} will return this context. * * @param handler the exception handler * @return a reference to this, so the API can be used fluently */ @Fluent Context exceptionHandler(@Nullable Handler handler); /** * @return the current exception handler of this context */ @GenIgnore @Nullable Handler exceptionHandler(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy