Class CallbackScope

java.lang.Object
org.atmosphere.inject.CallbackScope

public final class CallbackScope extends Object
The resource whose callback runs on the calling thread, which the request scoped @Inject fields of a shared service resolve.

One managed service instance serves every client of its path, and each callback re-injects its own AtmosphereResource, AtmosphereRequest, AtmosphereResponse and AtmosphereResourceEvent into the shared fields just before it runs. A field therefore holds a proxy, which acts on one of two resources:

  • a proxy written into its field after the callback running on the calling thread started (the callback's own injection, or a concurrent callback's that replaced it in the field) resolves the resource of that callback, so concurrent callbacks never read each other's client;
  • any other proxy, a reference stored by an earlier callback (a map of connected users) or used outside every callback, acts on the resource it was injected for.
What decides is when the proxy was written into its field, not when it was created: a concurrent injection can create its proxy before the calling thread's callback starts and write it into the shared field after that callback's own injection. Which one never changes while a callback runs. One window remains, inherent to a field shared by concurrent callbacks: a reference a concurrent callback stored after the calling thread's callback started resolves, for the rest of that callback, the calling thread's resource.

An injection pass binds its resource to the injecting thread. A handler that runs a callback on a thread that injected nothing (a broadcast delivery, a @Disconnect a broadcast thread claimed) injects the callback's resource again and binds it itself. The framework brackets every callback that may bind with current() and restore(Binding), so a pooled thread never keeps the resource of a callback it ran earlier.

  • Method Details

    • current

      public static CallbackScope.Binding current()
      What the calling thread resolves now, to be handed back to restore(Binding) when the caller's own callback ends.
      Returns:
      the binding of the calling thread, or null
    • bind

      public static CallbackScope.Binding bind(AtmosphereResource resource, AtmosphereResourceEvent event)
      Run a callback of resource on the calling thread. A null resource (an event already destroyed) binds nothing. A callback of the resource the thread already runs one for (a request that injected it, a callback nested in another of the same resource) keeps its start, so the fields that injection filled still resolve it.
      Parameters:
      resource - the resource whose callback runs
      event - the event the callback runs for, or null for the resource's own
      Returns:
      the binding to restore(Binding) when the callback ends
    • restore

      public static void restore(CallbackScope.Binding previous)
      End a callback: the calling thread resolves again what it resolved when the callback started (an enclosing callback's resource, or nothing).
      Parameters:
      previous - the value current() or bind(org.atmosphere.cpr.AtmosphereResource, org.atmosphere.cpr.AtmosphereResourceEvent) returned when the callback started
    • unwrap

      public static AtmosphereResource unwrap(AtmosphereResource resource)
      The object an injected proxy acts on now (see the class description). Anything else is returned as is.
      Parameters:
      resource - a resource, possibly an injected proxy
      Returns:
      the resource itself, never a proxy