pl.morgwai.base.guice.scopes.ContextScope Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of guice-context-scopes Show documentation
Show all versions of guice-context-scopes Show documentation
Classes for building Guice scopes, that get automatically transferred when dispatching work to other threads
// Copyright (c) Piotr Morgwai Kotarbinski, Licensed under the Apache License, Version 2.0
package pl.morgwai.base.guice.scopes;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
/**
* Scopes objects to a call context obtained from the associated {@link ContextTracker}.
*/
public class ContextScope> implements Scope {
final ContextTracker tracker;
final String name;
public String getName() { return name; }
public ContextScope(String name, ContextTracker tracker) {
this.name = name;
this.tracker = tracker;
}
/**
* @throws RuntimeException if there's no context for the current thread. This most commonly
* happens when providing a callback to some async method without transferring the context. Use
* static helper methods {@link ContextTrackingExecutor#getActiveContexts(ContextTracker...)}
* and {@link ContextTrackingExecutor#executeWithinAll(java.util.List, Runnable)} to fix it:
*
* class MyClass {
*
* @Inject ContextTracker<ContextT1> tracker1;
* @Inject ContextTracker<ContextT2> tracker2;
*
* void myMethod(Object param) {
* // myMethod code
* var activeCtxList = ContextTrackingExecutor.getActiveContexts(tracker1, tracker2);
* someAsyncMethod(param, (callbackParam) ->
* ContextTrackingExecutor.executeWithinAll(activeCtxList, () -> {
* // callback code
* }
* ));
* }
* }
*/
@Override
public Provider scope(Key key, Provider unscoped) {
return () -> {
try {
return tracker.getCurrentContext().provideAttributeIfAbsent(key, unscoped);
} catch (NullPointerException e) {
// NPE here is a result of a bug that will be usually eliminated in development
// phase and not happen in production, so we catch NPE instead of checking manually
// each time.
throw new RuntimeException("no context for thread "
+ Thread.currentThread().getName() + " in scope " + name
+ ". See javadoc for ContextScope.scope(...)");
}
};
}
@Override
public String toString() {
return name;
}
}