com.sun.xml.ws.api.pipe
Class Fiber

java.lang.Object
  extended by com.sun.xml.ws.api.pipe.Fiber
All Implemented Interfaces:
Runnable

public final class Fiber
extends Object
implements Runnable

User-level thread. Represents the execution of one request/response processing.

JAX-WS RI is capable of running a large number of request/response concurrently by using a relatively small number of threads. This is made possible by utilizing a Fiber — a user-level thread that gets created for each request/response processing.

A fiber remembers where in the pipeline the processing is at, what needs to be executed on the way out (when processing response), and other additional information specific to the execution of a particular request/response.

Suspend/Resume

Fiber can be suspended by a Tube. When a fiber is suspended, it will be kept on the side until it is resumed. This allows threads to go execute other runnable fibers, allowing efficient utilization of smaller number of threads.

Context-switch Interception

FiberContextSwitchInterceptor allows Tubes and Adapters to perform additional processing every time a thread starts running a fiber and stops running it.

Context ClassLoader

Just like thread, a fiber has a context class loader (CCL.) A fiber's CCL becomes the thread's CCL when it's executing the fiber. The original CCL of the thread will be restored when the thread leaves the fiber execution.

Debugging Aid

Because Fiber doesn't keep much in the call stack, and instead use conts to store the continuation, debugging fiber related activities could be harder.

Setting the LOGGER for FINE would give you basic start/stop/resume/suspend level logging. Using FINER would cause more detailed logging, which includes what tubes are executed in what order and how they behaved.

When you debug the server side, consider setting serializeExecution to true, so that execution of fibers are serialized. Debugging a server with more than one running threads is very tricky, and this switch will prevent that. This can be also enabled by setting the system property on. See the source code.


Nested Class Summary
static interface Fiber.CompletionCallback
          Callback to be invoked when a Fiber finishs execution.
 
Field Summary
 Engine owner
           
static boolean serializeExecution
          Set this boolean to true to execute fibers sequentially one by one.
 
Constructor Summary
Fiber(Engine engine)
           
 
Method Summary
 void addInterceptor(FiberContextSwitchInterceptor interceptor)
          Adds a new FiberContextSwitchInterceptor to this fiber.
static Fiber current()
          Gets the current fiber that's running.
 ClassLoader getContextClassLoader()
          Gets the context ClassLoader of this fiber.
 Packet getPacket()
          Gets the current Packet associated with this fiber.
 boolean isAlive()
          Returns true if this fiber is still running or suspended.
static boolean isSynchronous()
          (ADVANCED) Returns true if the current fiber is being executed synchronously.
 boolean removeInterceptor(FiberContextSwitchInterceptor interceptor)
          Removes a FiberContextSwitchInterceptor from this fiber.
 void resume(Packet response)
          Wakes up a suspended fiber.
 void run()
          Deprecated. 
 Packet runSync(Tube tubeline, Packet request)
          Runs a given Tube (and everything thereafter) synchronously.
 ClassLoader setContextClassLoader(ClassLoader contextClassLoader)
          Sets the context ClassLoader of this fiber.
 void start(Tube tubeline, Packet request, Fiber.CompletionCallback completionCallback)
          Starts the execution of this fiber asynchronously.
 String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

owner

public final Engine owner

serializeExecution

public static volatile boolean serializeExecution
Set this boolean to true to execute fibers sequentially one by one. See class javadoc.

Constructor Detail

Fiber

Fiber(Engine engine)
Method Detail

start

public void start(@NotNull
                  Tube tubeline,
                  @NotNull
                  Packet request,
                  @Nullable
                  Fiber.CompletionCallback completionCallback)
Starts the execution of this fiber asynchronously.

This method works like Thread.start().

Parameters:
tubeline - The first tube of the tubeline that will act on the packet.
request - The request packet to be passed to startPoint.processRequest().
completionCallback - The callback to be invoked when the processing is finished and the final response packet is available.
See Also:
runSync(Tube,Packet)

resume

public void resume(@NotNull
                   Packet response)
Wakes up a suspended fiber.

If a fiber was suspended from the Tube.processRequest(Packet) method, then the execution will be resumed from the corresponding Tube.processResponse(Packet) method with the specified response packet as the parameter.

If a fiber was suspended from the Tube.processResponse(Packet) method, then the execution will be resumed from the next tube's Tube.processResponse(Packet) method with the specified response packet as the parameter.

This method is implemented in a race-free way. Another thread can invoke this method even before this fiber goes into the suspension mode. So the caller need not worry about synchronizing NextAction.suspend() and this method.


addInterceptor

public void addInterceptor(@NotNull
                           FiberContextSwitchInterceptor interceptor)
Adds a new FiberContextSwitchInterceptor to this fiber.

The newly installed fiber will take effect immediately after the current tube returns from its Tube.processRequest(Packet) or Tube.processResponse(Packet), before the next tube begins processing.

So when the tubeline consists of X and Y, and when X installs an interceptor, the order of execution will be as follows:

  1. X.processRequest()
  2. interceptor gets installed
  3. interceptor.execute() is invoked
  4. Y.processRequest()


removeInterceptor

public boolean removeInterceptor(@NotNull
                                 FiberContextSwitchInterceptor interceptor)
Removes a FiberContextSwitchInterceptor from this fiber.

The removal of the interceptor takes effect immediately after the current tube returns from its Tube.processRequest(Packet) or Tube.processResponse(Packet), before the next tube begins processing.

So when the tubeline consists of X and Y, and when Y uninstalls an interceptor on the way out, then the order of execution will be as follows:

  1. Y.processResponse() (notice that this happens with interceptor.execute() in the callstack)
  2. interceptor gets uninstalled
  3. interceptor.execute() returns
  4. X.processResponse()

Returns:
true if the specified interceptor was removed. False if the specified interceptor was not registered with this fiber to begin with.

getContextClassLoader

@Nullable
public ClassLoader getContextClassLoader()
Gets the context ClassLoader of this fiber.


setContextClassLoader

public ClassLoader setContextClassLoader(@Nullable
                                         ClassLoader contextClassLoader)
Sets the context ClassLoader of this fiber.


run

@Deprecated
public void run()
Deprecated. 

DO NOT CALL THIS METHOD. This is an implementation detail of Fiber.

Specified by:
run in interface Runnable

runSync

@NotNull
public Packet runSync(@NotNull
                              Tube tubeline,
                              @NotNull
                              Packet request)
Runs a given Tube (and everything thereafter) synchronously.

This method blocks and returns only when all the successive Tubes complete their request/response processing. This method can be used if a Tube needs to fallback to synchronous processing.

Example:

 class FooTube extends AbstractFilterTubeImpl {
   NextAction processRequest(Packet request) {
     // run everything synchronously and return with the response packet
     return doReturnWith(Fiber.current().runSync(next,request));
   }
   NextAction processResponse(Packet response) {
     // never be invoked
   }
 }
 

Parameters:
tubeline - The first tube of the tubeline that will act on the packet.
request - The request packet to be passed to startPoint.processRequest().
Returns:
The response packet to the request.
See Also:
start(Tube, Packet, CompletionCallback)

toString

public String toString()
Overrides:
toString in class Object

getPacket

@Nullable
public Packet getPacket()
Gets the current Packet associated with this fiber.

This method returns null if no packet has been associated with the fiber yet.


isAlive

public boolean isAlive()
Returns true if this fiber is still running or suspended.


isSynchronous

public static boolean isSynchronous()
(ADVANCED) Returns true if the current fiber is being executed synchronously.

Fiber may run synchronously for various reasons. Perhaps this is on client side and application has invoked a synchronous method call. Perhaps this is on server side and we have deployed on a synchronous transport (like servlet.)

When a fiber is run synchronously (IOW by runSync(Tube, Packet)), further invocations to runSync(Tube, Packet) can be done without degrading the performance.

So this value can be used as a further optimization hint for advanced Tubes to choose the best strategy to invoke the next Tube. For example, a tube may want to install a FiberContextSwitchInterceptor if running async, yet it might find it faster to do runSync(Tube, Packet) if it's already running synchronously.


current

@NotNull
public static Fiber current()
Gets the current fiber that's running.

This works like Thread.currentThread(). This method only works when invoked from Tube.