Как использовать вызываемый Java-интерфейс для асинхронной обработки элементов очереди? - PullRequest
0 голосов
/ 22 октября 2018

Я использовал для реализации интерфейса Runnable для peek() элемент из очереди и отправил его в API.

Но теперь мне нужно использовать Callable интерфейс для peek() очереди и отправить элемент в API.Если вернуть 200, то удалить элемент из очереди.

Вот код, который я использовал для реализации этой функциональности.Как я могу изменить код?Любые примеры или ссылки по этому поводу?Спасибо.

public class QueueProcessor implements Runnable{

private static ObjectQueue<JSONObject> objectQueue;

static {
 objectQueue = new ObjectQueue<JSONObject>();
}

public void run() {

//add items to the queue
   objectQueue.add(jsonObeject)
    Random r = new Random();
    try {
        while (true) {
            try {
                if (!objectQueue.isEmpty()) {
                    JSONObject o = objectQueue.remove();
                    sendRequest(o.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    } 
}

 public void sendRequest(JSONObject json) {

 Client client = ClientBuilder.newClient();
 WebTarget baseTarget = client.target("someUrl");
 Invocation.Builder builder = baseTarget.request();
 Response response = builder.post(Entity.entity(json.toString(), MediaType.APPLICATION_JSON));

 int code = response.getStatus();   
 if (200 == code) {
    objectQueue.remove();
 }  

}

1 Ответ

0 голосов
/ 22 октября 2018

Просто, чтобы начать, обратитесь к этому другому вопросу SO

и обратите внимание на пункт # 1 в самом вопросе.

Чтобы выполнить асинхронные вызовы, сначала необходимо отделить - отправку / выполнение задачи (выбрать элемент из очереди и выполнить вызов API) и обработку ответа после вызова API (удалить элемент из очереди, если статус ответа равен 200).Эта развязка может быть достигнута с помощью - ExecutorService

Итак, сначала введите ExecutorService в ваш код Runnable, т.е. начните выполнение Runnable с некоторого класса контроллера (класса с методом main), которыйиспользует Executor для отправки / выполнения запросов.Вы не показали, как вы запускаете свою тему, так что вы, возможно, уже делаете это.

Теперь измените ваш Runnable на Callable<Response>, то есть создайте Callable, похожий на ваш Runnable и реализуйте Callable<Response>, а в методе call() сделайте вызов API.Вам необходимо предоставить ваш ObjectQueue<JSONObject> вашему классу основного контроллера и этому Callable, чтобы реализация очереди была поточно-ориентированной, или вам нужно сделать метод call() поточно-ориентированным.

Я имею в виду, что вы либо зацикливаетесь на своей очереди в контроллере и продолжаете отправлять запросы на каждый элемент, либо передаете всю очередь в Callble, и там выполняется блокировка - это ваш вызов.

Обратите внимание, что до этой точки метод call() возвращает значение - Может вызываться , в то время как run() метод Runnable не возвращает никакого значения, и это является существенным отличиеммежду двумя.

Теперь вернемся к классу контроллера - метод submit или execute превратит ваш Response в Future submit

Теперь используйте комбинацию isDone() &get() методы в вашем Future для удаления элемента из очереди.

Помните, что вы должны иметь возможность идентифицировать обработанный объект в очереди из ответа API - если нет, то вам нужно объединить ответ API с отправленным JSONObject и обернуть его в Future, чтобы выяснить, какой объект нужноудалить к.Только статуса недостаточно, и вам может понадобиться другая структура данных для хранения объектов, если очередь ограничена для удаления только верхнего элемента.Эта сложность не возникает, если вы просто заменяете runnable на callable, но не хотите делать вашу программу действительно асинхронной.

Это просто общие рекомендации, и я не буду делать готовый код.Вы найдете много примеров в Интернете, если ваши основы верны.Кроме того, при вставке кода обязательно попробуйте включить import операторов.

Несколько ссылок

Как отправлять параллельные запросы GET и ждать результатов ответов?

Как отправлять несколько асинхронных запросов в разные сетиуслуги

...