santazhang/simple-rpc — pull request #1 by visualzhou (2013-06-06 22:17:34+00:00)
Title: Add Callback mechanism

To make writing callback easier, the Callback templates are introduced and makeCallable() is handy to bind functions to objects. Here is an example.
https://github.com/visualzhou/simple-rpc/blob/callback/test/callback_test.cc#L85
```
rpc::Runnable* cb = makeCallable(&Counter::inc, &c); // Bind function to object.
pool->run_async(cb); // cb is deleted after running by pool.
```
More examples could be found in that test file.

The best thing is currying. It is demonstrated in
https://github.com/visualzhou/simple-rpc/blob/callback/test/demo_client.cc
Here is the function declared.
```
class CallbackHanler {
public:
void onCallback(Client* cl, int* rpc_counter, Future* fu) { ... }
}
```
Call `makeCallable()` to get a FutureCallback.
```
CallbackHanler handler; // Thread-safe
for (int i = 0; i < concurrency; i++) {
FutureAttr attr;
attr.callback = makeCallable(&CallbackHanler::onCallback, &handler, cl, &rpc_counter);
// Start the endless chains of callbacks until close_and_release.
Future* fu = MathProxy(cl).async_is_prime(rand(), attr);
if (fu != NULL) {
fu->release();
}
}
```

Now the Runnable and FutureCallback are just `typedef` and their interfaces are kept the same as before. All the code we have now still work.
```
typedef Callback Runnable;
typedef Callback FutureCallback;
```

Notice we need to wrap all logic in classes and have its object before using it. This is reasonable because all logic is organized together instead of spreading all around. Image the change when writing coordinators in Lynx and throughout tests.