本文主要研究一下cheddar的PendingResult
Cheddar/cheddar/cheddar-application/src/main/java/com/clicktravel/cheddar/application/pending/result/PendingResult.java
class PendingResult {
private static final long TIMEOUT_SECONDS = 30;
private final CountDownLatch countdownLatch = new CountDownLatch(1);
private Result result;
/**
* Offers a {@link Result}, returning immediately.
* @param result {@link Result} to offer
*/
public void offerResult(final Result result) {
this.result = result;
countdownLatch.countDown();
}
/**
* Polls for a {@link Result}, blocking until it is offered by some other thread. If the result has already been
* offered, the result is returned immediately.
* @return {@link Result} obtained, potentially after blocking
* @throws InterruptedException, PendingResultTimeoutException
*/
public Result pollResult() throws InterruptedException, PendingResultTimeoutException {
if (!countdownLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
throw new PendingResultTimeoutException();
}
return result;
}
}
PendingResult定义了offerResult、pollResult方法;offerResult方法设置result,然后通过countdownLatch通过pollResult;pollResult方法等待TIMEOUT_SECONDS,若还没有结果抛出PendingResultTimeoutException
Cheddar/cheddar/cheddar-application/src/main/java/com/clicktravel/cheddar/application/pending/result/PendingResultHandler.java
@Component
public class PendingResultHandler {
private final PendingResultsHolder pendingResultsHolder;
private final String applicationName;
private final XStream xStream = new XStream();
@Autowired
public PendingResultHandler(final PendingResultsHolder pendingResultsHolder,
@Value("${server.application.name}") final String applicationName) {
this.pendingResultsHolder = pendingResultsHolder;
this.applicationName = applicationName;
}
/**
* Creates a {@link PendingResult} stored on the local application instance
* @return pendingResultId Unique identifier of created {@PendingResult}
*/
public String createPendingResult() {
return pendingResultsHolder.create();
}
/**
* Removes a {@link PendingResult} stored on the local application instance
* @param pendingResultId ID of {@link PendingResult} to remove
*/
public void removePendingResult(final String pendingResultId) {
pendingResultsHolder.remove(pendingResultId);
}
/**
* Polls a {@link PendingResult} stored on the local application instance for a returned value, blocking until a
* value is offered or an exception is thrown
* @param pendingResultId ID of locally stored {@link PendingResult}
* @return Value from returned result
* @throws Exception If exception was thrown
*/
public Object pollValue(final String pendingResultId) throws Exception {
final PendingResult pendingResult = pendingResultsHolder.get(pendingResultId);
return pendingResult.pollResult().getValue();
}
/**
* Offers a return value for a {@link PendingResult}, which is possibly stored on a different (remote) application
* instance
* @param pendingResultId ID of {@link PendingResult} to offer value to
* @param value Value to offer
*/
public void offerValue(final String pendingResultId, final Object value) {
offerResult(pendingResultId, new SimpleResult(value));
}
/**
* Offers a thrown exception for a {@link PendingResult}, which is possibly stored on a different (remote)
* application instance
* @param pendingResultId of {@link PendingResult} to offer thrown exception to
* @param exception Thrown exception to offer
*/
public void offerException(final String pendingResultId, final Exception exception) {
offerResult(pendingResultId, new ExceptionResult(exception));
}
private void offerResult(final String pendingResultId, final Result result) {
final PendingResultOfferedEvent event = new PendingResultOfferedEvent();
event.setTargetApplicationName(applicationName);
event.setPendingResultId(pendingResultId);
event.setResultXml(toCompactXml(result));
SystemEventPublisher.instance().publishEvent(event);
}
private String toCompactXml(final Object object) {
final StringWriter stringWriter = new StringWriter();
xStream.marshal(object, new CompactWriter(stringWriter));
return stringWriter.toString();
}
}
PendingResultHandler提供了removePendingResult、pollValue、offerValue、offerException方法;offerResult方法创建并发布PendingResultOfferedEvent
cheddar的PendingResult定义了offerResult、pollResult方法;PendingResultHandler提供了removePendingResult、pollValue、offerValue、offerException方法。