聊聊cheddar的PendingResult

本文主要研究一下cheddar的PendingResult

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

PendingResultHandler

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方法。

doc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章