<document>
<deftable>
Configures the WorkResource
The resource implementation launches the Work task and provides common state.
The work task sleeps and counts.
The starting page for the tutorial
</deftable>

A `Work` task implements the `javax.resource.work.Work` interface. Like the familiar `Runnable` interface, `Work` has a public `run()` method as the main thread method. `Work` adds a `release()` method which allows Resin to notify the task when the resource should shut down.

The example task increments a counter and sleeps. The `run` method has the main loop.

The only complexity in the task implements the `release()` capability. The `_isActive` flag indicates whether the server is still alive. It is important that `_isActive` is set before the work task is submitted to avoid timing issues. In other words, it would be a mistake to set `_isActive = true` in the `run()` method since Resin could call `release()` before the run thread started.

The task uses `wait(long)` for sleeping. The `release()` will wake the task to let it shut down. In a work task, the main blocking calls should have timeouts or will be interruptable. A real application like a chat server might be reading a socket or waiting for a new connection. Those calls need timeouts so the task can shut down the service at the appropriate time.

import javax.resource.Work; public class WorkTask implements Work { private volatile boolean _isActive = true; private int _count; int getCount() { return _count; } public void run() { while (_isActive) { _count++; try { synchronized (this) { wait(10000); } } catch (Throwable e) { } } } public void release() { _isActive = false; try { synchronized (this) { notifyAll(); } } catch (Throwable e) { } }

The `WorkResource` in this example is simple since it only needs to launch the work task. As with the previous examples, the resource extends `com.caucho.jca.AbstractResourceAdapter` to simplify the example.

import com.caucho.jca.AbstractResourceAdapter; public class WorkResource extends AbstractResourceAdapter { public void start(BootstrapContext ctx) throws ResourceAdapterInternalException { WorkTask work = new WorkTask(); WorkManager workManager = ctx.getWorkManager(); try { // Submits the work, but does not wait for the result. // In other words, it spawns a new thread workManager.startWork(work); } catch (WorkException e) { throw new ResourceAdapterInternalException(e); } } public String toString() { return "WorkResource[" + _workTask.getCount() + "]"; } }
</document>