001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation.client.jaxrs.spi;
020
021import java.util.concurrent.ExecutorService;
022import java.util.concurrent.Executors;
023import java.util.concurrent.ThreadFactory;
024import java.util.concurrent.TimeUnit;
025import java.util.function.Supplier;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public abstract class AsyncAutomationClient extends AbstractAutomationClient {
034
035    private static final Log log = LogFactory.getLog(AsyncAutomationClient.class);
036
037    protected ExecutorService async;
038
039    /**
040     * Timeout in milliseconds for the wait of the asynchronous thread pool termination. Default value: 2 seconds.
041     */
042    protected long asyncAwaitTerminationTimeout = 2000;
043
044    protected static ExecutorService getExecutorService() {
045        return Executors.newCachedThreadPool(new ThreadFactory() {
046            @Override
047            public Thread newThread(Runnable r) {
048                return new Thread("AutomationAsyncExecutor");
049            }
050        });
051    }
052
053    /**
054     * Instantiates a new asynchronous automation client with the default timeout for the wait of the asynchronous
055     * thread pool termination: 2 seconds.
056     */
057    public AsyncAutomationClient(String url) {
058        this(url, getExecutorService());
059    }
060
061    /**
062     * Instantiates a new asynchronous automation client with the default timeout for the wait of the asynchronous
063     * thread pool termination: 2 seconds.
064     *
065     * @since 10.10
066     */
067    public AsyncAutomationClient(Supplier<String> urlSupplier) {
068        this(urlSupplier, getExecutorService());
069    }
070
071    /**
072     * Instantiates a new asynchronous automation client with the given asynchronous executor and the default timeout
073     * for the wait of the asynchronous thread pool termination: 2 seconds.
074     */
075    public AsyncAutomationClient(String url, ExecutorService executor) {
076        super(url);
077        async = executor;
078    }
079
080    /**
081     * Instantiates a new asynchronous automation client with the given asynchronous executor and the default timeout
082     * for the wait of the asynchronous thread pool termination: 2 seconds.
083     *
084     * @since 10.10
085     */
086    public AsyncAutomationClient(Supplier<String> urlSupplier, ExecutorService executor) {
087        super(urlSupplier);
088        async = executor;
089    }
090
091    /**
092     * Instantiates a new asynchronous automation client with the given timeout in milliseconds for the wait of the
093     * asynchronous thread pool termination.
094     *
095     * @since 5.7
096     */
097    public AsyncAutomationClient(String url, long asyncAwaitTerminationTimeout) {
098        this(url);
099        this.asyncAwaitTerminationTimeout = asyncAwaitTerminationTimeout;
100    }
101
102    /**
103     * Instantiates a new asynchronous automation client with the given asynchronous executor and the given timeout in
104     * milliseconds for the wait of the asynchronous thread pool termination.
105     *
106     * @since 5.7
107     */
108    public AsyncAutomationClient(String url, ExecutorService executor, long asyncAwaitTerminationTimeout) {
109        this(url, executor);
110        this.asyncAwaitTerminationTimeout = asyncAwaitTerminationTimeout;
111    }
112
113    @Override
114    public void asyncExec(Runnable runnable) {
115        async.execute(runnable);
116    }
117
118    @Override
119    public synchronized void shutdown() {
120        try {
121            async.awaitTermination(asyncAwaitTerminationTimeout, TimeUnit.MILLISECONDS);
122        } catch (InterruptedException e) {
123            Thread.currentThread().interrupt();
124            throw new RuntimeException(e);
125        }
126        super.shutdown();
127        async = null;
128    }
129
130}