我一直在考虑用于异步请求/响应的通用通用/可取消接口。要求如下,必须:
所以这是我的第一次尝试:
interface AsyncOperation<INPUT, OUTPUT> {
Future<OUTPUT> execute(INPUT in, AsyncCallback<OUTPUT> callback);
}
interface AsyncCallback<OUTPUT> {
void done(OUTPUT output);
}
用法:
// completely async operation
operation.execute("Test", new AsyncCallback<String> {
public void done(String output) {
// process result...
}
});
// sync operation with cancellation after timeout
Future<String> future = operation.execute("Test", null);
try {
String result = future.get(1000);
} catch(TimeoutException ex) {
future.cancel();
}
缺点
对于某些情况,Google Protocol Buffers服务方法遵循相对类似的模式:
void [methodname](RpcController controller,
[RequestClass] request, RpcCallback<[ResponseClass]> callback);
有更好的想法吗?
答案 0 :(得分:1)
您需要INPUT类型参数吗?将输入作为状态保存的操作对象不会更容易,如:
void greet(final String name) {
new AsyncOperation<Object>() {
@Override Object doIt() {
System.out.println("Hello " + name + "!");
}
}.execute(null);
}
这样,调用者可以以类型安全的方式传递任意数量的参数。
此外,调用回调并返回未来似乎是一种奇怪的用法。你确定需要吗?您可以提供两个执行方法,一个返回将来,另一个调用回调。
答案 1 :(得分:0)
看看jetlang。它支持异步操作和请求 - 响应模型。以下是他们测试的一个例子:
@Test
public void simpleRequestResponse() throws InterruptedException {
Fiber req = new ThreadFiber();
Fiber reply = new ThreadFiber();
req.start();
reply.start();
RequestChannel<String, Integer> channel = new MemoryRequestChannel<String, Integer>();
Callback<Request<String, Integer>> onReq = new Callback<Request<String, Integer>>() {
public void onMessage(Request<String, Integer> message) {
assertEquals("hello", message.getRequest());
message.reply(1);
}
};
channel.subscribe(reply, onReq);
final CountDownLatch done = new CountDownLatch(1);
Callback<Integer> onReply = new Callback<Integer>() {
public void onMessage(Integer message) {
assertEquals(1, message.intValue());
done.countDown();
}
};
AsyncRequest.withOneReply(req, channel, "hello", onReply);
assertTrue(done.await(10, TimeUnit.SECONDS));
req.dispose();
reply.dispose();
}
答案 2 :(得分:0)
好的,很难回答你自己的问题,但我已经提出了一套适合这个问题的课程:
// the main Async operation interface
public interface AsyncOperation<OUTPUT, INPUT> {
public AsyncController execute(INPUT input,
AsyncCallback<OUTPUT> callback);
}
// the callback that gets called when the operation completes
public interface AsyncCallback<OUTPUT> {
public void done(AsyncResult<OUTPUT> output);
}
// provides the ability to cancel operations
public interface AsyncController {
void cancel();
}
// this provides a convenient way to manage a response that is either a
// value or an exception
public class AsyncResult<VALUE> {
private final VALUE value;
private final Throwable throwable;
private AsyncResult(VALUE value, Throwable throwable) {
this.value = value;
this.throwable = throwable;
}
public AsyncResult(VALUE value) {
this(value, null);
}
public AsyncResult(Throwable throwable) {
this((VALUE) null, throwable);
}
public VALUE value() throws Throwable {
if(throwable != null) {
throw throwable;
} else {
return value;
}
}
}