Using Runnable Servers
The
RWTThreadIOUFunction used in the example is generally not suitable for an active object implementation that must accept any number of asynchronous requests from a client interface.
It is better to use one of the runnable server classes,
RWRunnableServer or
RWServerPool, to provide the internal thread or threads required by the active object. These classes are suitable because they are designed to continuously accept and execute other runnable objects. This allows you to package individual operations as synchronous runnables that can be passed to the internal server for execution. Runnable servers are covered in detail in
The Server Classes.In
Example 23, individual operations are executed asynchronously relative to the thread that requests them, but simultaneous requests cannot be processed concurrently. This limitation is a consequence of choosing the single-threaded
RWRunnableServer class for the internal server thread.
If an active object design can benefit from increased concurrency, then the multithreaded
RWServerPool class should be used instead.
Example 23 – Using a single-threaded runnable server class
#include <rw/thread/RWRunnableServer.h>
#include <rw/thread/RWTRunnableIOUFunction.h>
#include <rw/itc/RWTIOUResult.h>
#include <rw/functor/rwBind.h>
#include <iostream>
using namespace std;
class ServiceProvider; // Forward reference for inlines!
class ServiceProvider {
private:
RWRunnableServer server_;
protected:
int syncService() // 1
{
int status = 0;
// Do something useful that produces a status
// value indicating success or failure
rwSleep(1000); // Waste some time...
return status;
}
public:
ServiceProvider() { // 2
server_ = RWRunnableServer::make();
server_.start();
}
~ServiceProvider() { // 3
server_.stop();
server_.join();
}
RWTIOUResult<int> asyncService() { // 4
RWTRunnableIOUFunction<int> runnable;
runnable = RWTRunnableIOUFunction<int>::make(rwBind(
&ServiceProvider::syncService,
this));
server_.enqueue(runnable);
return runnable.result();
}
};
void
main()
{
ServiceProvider provider; // 5
cout << "Calling asynchronous service..." << endl;
RWTIOUResult<int> iou = provider.asyncService(); // 6
cout << "Redeemed value of IOU: " << iou << endl; // 7
} // 8