org.codelibs.fess.suggest.concurrent.Deferred Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2012-2024 CodeLibs Project and the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.codelibs.fess.suggest.concurrent;
import java.util.ArrayList;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import org.codelibs.core.exception.InterruptedRuntimeException;
import org.codelibs.fess.suggest.exception.SuggesterException;
import org.codelibs.fess.suggest.request.Response;
public class Deferred {
private RESPONSE response = null;
private Throwable error = null;
private final Promise promise = new Promise();
private final Queue> doneCallbacks = new LinkedBlockingQueue<>();
private final Queue> errorCallbacks = new LinkedBlockingQueue<>();
private final CountDownLatch latch = new CountDownLatch(1);
public void resolve(final RESPONSE r) {
final ArrayList> executeCallbacks;
synchronized (Deferred.this) {
if (response != null || error != null) {
return;
}
response = r;
executeCallbacks = new ArrayList<>(doneCallbacks.size());
Consumer callback;
while ((callback = doneCallbacks.poll()) != null) {
executeCallbacks.add(callback);
}
}
if (executeCallbacks.size() > 0) {
try {
executeCallbacks.stream().forEach(callback -> callback.accept(response));
} catch (final Exception ignore) {}
}
latch.countDown();
}
public void reject(final Throwable t) {
final ArrayList> executeCallbacks;
synchronized (Deferred.this) {
if (response != null || error != null) {
return;
}
error = t;
executeCallbacks = new ArrayList<>(errorCallbacks.size());
Consumer callback;
while ((callback = errorCallbacks.poll()) != null) {
executeCallbacks.add(callback);
}
}
if (executeCallbacks.size() > 0) {
try {
executeCallbacks.stream().forEach(callback -> callback.accept(error));
} catch (final Exception ignore) {}
}
latch.countDown();
}
public Promise then(final Consumer consumer) {
return promise.then(consumer);
}
public Promise error(final Consumer consumer) {
return promise.error(consumer);
}
public Promise promise() {
return promise;
}
public class Promise {
public Promise then(final Consumer consumer) {
final ArrayList> executeCallbacks;
synchronized (Deferred.this) {
doneCallbacks.add(consumer);
executeCallbacks = new ArrayList<>(doneCallbacks.size());
if (response != null) {
Consumer callback;
while ((callback = doneCallbacks.poll()) != null) {
executeCallbacks.add(callback);
}
}
}
if (executeCallbacks.size() > 0) {
executeCallbacks.stream().forEach(callback -> callback.accept(response));
}
return this;
}
public Promise error(final Consumer consumer) {
final ArrayList> executeCallbacks;
synchronized (Deferred.this) {
errorCallbacks.add(consumer);
executeCallbacks = new ArrayList<>(errorCallbacks.size());
if (error != null) {
Consumer callback;
while ((callback = errorCallbacks.poll()) != null) {
executeCallbacks.add(callback);
}
}
}
if (executeCallbacks.size() > 0) {
executeCallbacks.stream().forEach(callback -> callback.accept(error));
}
return this;
}
public RESPONSE getResponse() {
return getResponse(1, TimeUnit.MINUTES);
}
public RESPONSE getResponse(final long time, final TimeUnit unit) {
try {
final boolean isTimeout = !latch.await(time, unit);
if (isTimeout) {
throw new SuggesterException("Request timeout. time:" + time + " unit:" + unit.name());
}
if (error != null) {
throw new SuggesterException(error);
}
return response;
} catch (final InterruptedException e) {
throw new InterruptedRuntimeException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy