Skip to content

Commit

Permalink
Context created from a vertx thread should not be recorded as a stick…
Browse files Browse the repository at this point in the history
…y context.
  • Loading branch information
vietj committed Aug 12, 2024
1 parent bab52b7 commit 334e2cd
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/main/java/io/vertx/core/Vertx.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static Future<Vertx> clusteredVertx(VertxOptions options) {
* @return The current context or {@code null} if there is no current context
*/
static @Nullable Context currentContext() {
return ContextInternal.current();
return ContextInternal.current(Thread.currentThread());
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/io/vertx/core/impl/ContextInternal.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ public interface ContextInternal extends Context {
/**
* @return the current context
*/
static ContextInternal current() {
Thread thread = Thread.currentThread();
static ContextInternal current(Thread thread) {
if (thread instanceof VertxThread) {
return ((VertxThread) thread).context();
} else {
Expand Down Expand Up @@ -237,7 +236,7 @@ default void execute(Handler<Void> task) {
* @return whether the current thread is running on this context
*/
default boolean isRunningOnContext() {
return current() == this && inThread();
return current(Thread.currentThread()) == this && inThread();
}

/**
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/io/vertx/core/impl/VertxImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -504,10 +504,18 @@ public EventLoopGroup getAcceptorEventLoopGroup() {
}

public ContextInternal getOrCreateContext() {
ContextInternal ctx = getContext();
Thread thread = Thread.currentThread();
ContextInternal ctx = getContext(thread);
if (ctx == null) {
// We are running embedded - Create a context
ctx = createEventLoopContext();
return createContext(thread);
}
return ctx;
}

private ContextInternal createContext(Thread thread) {
// We are running embedded - Create a context
ContextInternal ctx = createEventLoopContext();
if (!(thread instanceof VertxThread)) {
stickyContext.set(new WeakReference<>(ctx));
}
return ctx;
Expand Down Expand Up @@ -677,15 +685,23 @@ public long scheduleTimeout(ContextInternal context,
}

public ContextInternal getContext() {
ContextInternal context = ContextInternal.current();
return getContext(Thread.currentThread());
}

private ContextInternal getContext(Thread current) {
ContextInternal context = ContextInternal.current(current);
if (context != null && context.owner() == this) {
return context;
} else {
WeakReference<ContextInternal> ref = stickyContext.get();
return ref != null ? ref.get() : null;
return getStickyContext();
}
}

private ContextInternal getStickyContext() {
WeakReference<ContextInternal> ref = stickyContext.get();
return ref != null ? ref.get() : null;
}

public ClusterManager getClusterManager() {
return clusterManager;
}
Expand Down
27 changes: 27 additions & 0 deletions src/test/java/io/vertx/core/ContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1121,4 +1121,31 @@ public void testConcurrentLocalAccess() throws Exception {
}
}

@Test
public void testContextShouldNotBeStickyFromUnassociatedEventLoopThread() {
ContextInternal ctx = ((VertxInternal)vertx).createEventLoopContext();
testContextShouldNotBeStickyFromUnassociatedVertxThread(ctx);
}

@Test
public void testContextShouldNotBeStickyFromUnassociatedWorkerThread() {
ContextInternal ctx = ((VertxInternal)vertx).createWorkerContext();
testContextShouldNotBeStickyFromUnassociatedVertxThread(ctx);
}

private void testContextShouldNotBeStickyFromUnassociatedVertxThread(ContextInternal ctx) {
ctx.execute(() -> {
assertEquals(null, Vertx.currentContext());
Context created1 = vertx.getOrCreateContext();
assertNotSame(ctx, created1);
ctx.execute(() -> {
assertEquals(null, Vertx.currentContext());
Context created2 = vertx.getOrCreateContext();
assertNotSame(ctx, created2);
assertNotSame(created1, created2);
testComplete();
});
});
await();
}
}

0 comments on commit 334e2cd

Please sign in to comment.