All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.dezhik.sms.sender.AsyncSenderService Maven / Gradle / Ivy

There is a newer version: 0.1.3
Show newest version
package ru.dezhik.sms.sender;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import ru.dezhik.sms.sender.api.ApiCallback;
import ru.dezhik.sms.sender.api.ApiRequest;
import ru.dezhik.sms.sender.api.ApiRequestHandler;
import ru.dezhik.sms.sender.api.ApiResponse;

/**
 *
 * @author ilya.dezhin
 */
public class AsyncSenderService {
    private final SenderServiceConfiguration config;
    private final SenderService senderService;
    private final ExecutorService apiExecutors;

    public AsyncSenderService(SenderServiceConfiguration config) {
        this.config = config;
        this.senderService = new SenderService(config);
        this.apiExecutors = config.getExecutorService() != null
                ? config.getExecutorService()
                : Executors.newSingleThreadExecutor();
    }

    /**
     * Should be used if you want to process response by yourself
     * without callback mechanics.
     * Makes retries using {@link SenderServiceConfiguration#getRetryPolicies()} if necessary.
     * @param request API request to execute
     * @return response wrapped in {@link Future}.
     * Note that response could be null if network error occurred and retries didn't help.
     */
    public  Future execute(
            final ApiRequest request
    ) {
        return apiExecutors.submit(new Callable() {
            @Override
            public R call() {
                return senderService.execute(request);
            }
        });
    }

    /**
     *
     * @param request
     * @param callbacks which should be executed after response parsing
     */
    public  void execute(
            final ApiRequest request,
            final ApiCallback... callbacks
    ) {
        apiExecutors.submit(new Runnable() {
            @Override
            public void run() {
                final R response = senderService.execute(request);
                if (callbacks != null) {
                    for (final ApiCallback callback : callbacks) {
                        if (callback.apply(request, response)) {
                            callback.execute(request, response);
                        }
                    }
                }
            }
        });
    }

    /**
     * This method should be used if you want to change default handler for
     * {@link ApiRequest} instances or adding new API methods.
     *
     * @param requestClass specifies {@link Class} which instances would be processed by the handler
     * @param handler for validating and parsing requests of such type
     * @throws {@link IllegalArgumentException} if requestClass or handler is null.
     */
    public void registerHandler(Class requestClass, ApiRequestHandler handler) {
        senderService.registerHandler(requestClass, handler);
    }

    /**
     * 1. Initiates executor shutdown
     * 2. Waits for specified in configuration period of time for actively
     * executing tasks to terminate and tries to stop them if necessary.
     * 3. Initiates shutdown on the underlying {@link SenderService}
     * @throws InterruptedException if interrupted while waiting
     * @throws IOException if an I/O error occurs
     */
    public void shutdown() throws InterruptedException, IOException {
        apiExecutors.shutdown();
        if (!apiExecutors.awaitTermination(config.getAsyncTerminationTimeoutMs(), TimeUnit.MILLISECONDS)) {
            apiExecutors.shutdownNow();
        }
        senderService.shutdown();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy