Skip to content

Commit 7fbc36f

Browse files
committed
Handle properly shadow context in worker executor implementation.
Motivation: The implementation of worker executor assumes that a context is always a ContextImpl. Since we added support for shadow contexts, the implementation should handle this case as well. Changes: Update the worker executor implementation to handle the case of a shadow context.
1 parent 8e05f2b commit 7fbc36f

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

vertx-core/src/main/java/io/vertx/core/impl/ShadowContext.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,25 @@
5050
* middleware running on the actual context interacts with this context resources, middleware running on the shadow context
5151
* interacts with the shadow context resources.</p>
5252
*/
53-
final class ShadowContext extends ContextBase {
53+
public final class ShadowContext extends ContextBase {
5454

5555
final VertxInternal owner;
5656
final ContextBase delegate;
5757
private final EventLoopExecutor eventLoop;
58-
private final TaskQueue orderedTasks;
58+
final TaskQueue orderedTasks;
5959

60-
public ShadowContext(VertxInternal owner, EventLoopExecutor eventLoop, ContextInternal delegate) {
60+
ShadowContext(VertxInternal owner, EventLoopExecutor eventLoop, ContextInternal delegate) {
6161
super(((ContextBase)delegate).locals);
6262
this.owner = owner;
6363
this.eventLoop = eventLoop;
6464
this.delegate = (ContextBase) delegate;
6565
this.orderedTasks = new TaskQueue();
6666
}
6767

68+
public ContextInternal delegate() {
69+
return delegate;
70+
}
71+
6872
@Override
6973
public EventExecutor eventLoop() {
7074
return eventLoop;

vertx-core/src/main/java/io/vertx/core/impl/WorkerExecutorImpl.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,18 @@ public WorkerPool getPool() {
6161
@Override
6262
public <T> Future<@Nullable T> executeBlocking(Callable<T> blockingCodeHandler, boolean ordered) {
6363
ContextInternal context = vertx.getOrCreateContext();
64-
ContextImpl impl = context instanceof DuplicatedContext ? ((DuplicatedContext)context).delegate : (ContextImpl) context;
65-
return pool.executeBlocking(context, blockingCodeHandler, ordered ? impl.executeBlockingTasks : null);
64+
TaskQueue orderedTasks;
65+
if (ordered) {
66+
if (context instanceof ShadowContext) {
67+
orderedTasks = ((ShadowContext)context).orderedTasks;
68+
} else {
69+
ContextImpl impl = context instanceof DuplicatedContext ? ((DuplicatedContext)context).delegate : (ContextImpl) context;
70+
orderedTasks = impl.executeBlockingTasks;
71+
}
72+
} else {
73+
orderedTasks = null;
74+
}
75+
return pool.executeBlocking(context, blockingCodeHandler, orderedTasks);
6676
}
6777

6878
@Override

vertx-core/src/test/java/io/vertx/tests/context/ShadowContextTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package io.vertx.tests.context;
22

33
import io.netty.channel.EventLoop;
4+
import io.vertx.codegen.annotations.Nullable;
45
import io.vertx.core.*;
56
import io.vertx.core.buffer.Buffer;
67
import io.vertx.core.eventbus.EventBus;
78
import io.vertx.core.http.*;
89
import io.vertx.core.impl.LocalSeq;
10+
import io.vertx.core.impl.ShadowContext;
11+
import io.vertx.core.impl.VertxThread;
912
import io.vertx.core.internal.ContextInternal;
1013
import io.vertx.core.internal.VertxInternal;
1114
import io.vertx.core.net.NetClient;
@@ -40,6 +43,7 @@ protected void setUp() throws Exception {
4043
contextLocal = ContextLocal.registerLocal(Object.class);
4144
shadowVertx = (VertxInternal) Vertx.vertx();
4245
actualVertx = (VertxInternal) Vertx.vertx();
46+
disableThreadChecks();
4347
}
4448

4549
@Override
@@ -504,4 +508,29 @@ private void testGetOrCreateContextFromUnassociatedThread(Executor executor) {
504508
});
505509
await();
506510
}
511+
512+
@Test
513+
public void testWorkerExecutorExecuteBlocking() {
514+
WorkerExecutor exec = shadowVertx.createSharedWorkerExecutor("abc");
515+
ContextInternal actualCtx = actualVertx.getOrCreateContext();
516+
actualCtx.runOnContext(v1 -> {
517+
Thread expected = Thread.currentThread();
518+
ContextInternal shadowCtx = shadowVertx.getOrCreateContext();
519+
Future<Context> fut = exec.executeBlocking(() -> {
520+
ShadowContext ctx = (ShadowContext) Vertx.currentContext();
521+
assertNotSame(shadowCtx, ctx);
522+
assertSame(actualCtx, ctx.delegate());
523+
assertSame(shadowCtx.owner(), shadowVertx);
524+
return ctx;
525+
});
526+
fut.onComplete(onSuccess(res -> {
527+
ShadowContext ctx = (ShadowContext) Vertx.currentContext();
528+
assertSame(res, ctx);
529+
assertSame(shadowCtx.owner(), shadowVertx);
530+
assertSame(expected, Thread.currentThread());
531+
testComplete();
532+
}));
533+
});
534+
await();
535+
}
507536
}

0 commit comments

Comments
 (0)