Eagerly evaluate Providers in GuiceServletScopePropagator
In ReceiveCommits, the RequestPropagator is constructed in the main thread, and then used from within the worker thread to create another nested scope for the email sending task. If we defer getting from the Providers until wrapImpl() is called in the worker thread, then HttpCurrentUserProvider.get() is reevaluated in that thread, which fails since there is no HttpServletRequest/Response available. Instead, save the actual provided objects in GuiceServletScopePropagator so references to the same objects are available from any thread. This is safe because we explicitly only propagate objects we know to be threadsafe, and if they're safe to access from two threads, they should be safe from an arbitrary number. This should also work for nesting scopes; when a new GuiceServletScopePropagator is required, it will inject CurrentUser et al. using the previously seeded keys. Change-Id: I9e74f1b38d1e9d587b296f4b973666e7ffb9b68f
This commit is contained in:
@@ -36,9 +36,9 @@ import javax.annotation.Nullable;
|
||||
/** Propagator for Guice's built-in servlet scope. */
|
||||
public class GuiceRequestScopePropagator extends RequestScopePropagator {
|
||||
|
||||
private final Provider<String> urlProvider;
|
||||
private final Provider<SocketAddress> remotePeerProvider;
|
||||
private final Provider<CurrentUser> currentUserProvider;
|
||||
private final String url;
|
||||
private final SocketAddress peer;
|
||||
private final CurrentUser user;
|
||||
|
||||
@Inject
|
||||
GuiceRequestScopePropagator(
|
||||
@@ -46,9 +46,9 @@ public class GuiceRequestScopePropagator extends RequestScopePropagator {
|
||||
@RemotePeer Provider<SocketAddress> remotePeerProvider,
|
||||
Provider<CurrentUser> currentUserProvider) {
|
||||
super(ServletScopes.REQUEST);
|
||||
this.urlProvider = urlProvider;
|
||||
this.remotePeerProvider = remotePeerProvider;
|
||||
this.currentUserProvider = currentUserProvider;
|
||||
this.url = urlProvider != null ? urlProvider.get() : null;
|
||||
this.peer = remotePeerProvider.get();
|
||||
this.user = currentUserProvider.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,17 +61,14 @@ public class GuiceRequestScopePropagator extends RequestScopePropagator {
|
||||
// Request scopes appear to use specific keys in their map, instead of only
|
||||
// providers. Add bindings for both the key to the instance directly and the
|
||||
// provider to the instance to be safe.
|
||||
String url = urlProvider.get();
|
||||
seedMap.put(Key.get(typeOfProvider(String.class), CanonicalWebUrl.class),
|
||||
Providers.of(url));
|
||||
seedMap.put(Key.get(String.class, CanonicalWebUrl.class), url);
|
||||
|
||||
SocketAddress peer = remotePeerProvider.get();
|
||||
seedMap.put(Key.get(typeOfProvider(SocketAddress.class), RemotePeer.class),
|
||||
Providers.of(peer));
|
||||
seedMap.put(Key.get(SocketAddress.class, RemotePeer.class), peer);
|
||||
|
||||
CurrentUser user = currentUserProvider.get();
|
||||
seedMap.put(Key.get(typeOfProvider(CurrentUser.class)), Providers.of(user));
|
||||
seedMap.put(Key.get(CurrentUser.class), user);
|
||||
|
||||
|
Reference in New Issue
Block a user