@@ -0,0 +1,3614 @@
+/*%0A * The MIT License (MIT)%0A *%0A * Copyright (c) 2016 Lachlan Dowding%0A *%0A * Permission is hereby granted, free of charge, to any person obtaining a copy%0A * of this software and associated documentation files (the %22Software%22), to deal%0A * in the Software without restriction, including without limitation the rights%0A * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell%0A * copies of the Software, and to permit persons to whom the Software is%0A * furnished to do so, subject to the following conditions:%0A *%0A * The above copyright notice and this permission notice shall be included in all%0A * copies or substantial portions of the Software.%0A *%0A * THE SOFTWARE IS PROVIDED %22AS IS%22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR%0A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,%0A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE%0A * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER%0A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,%0A * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE%0A * SOFTWARE.%0A */%0A%0Apackage permafrost.tundra.server.invoke;%0A%0Aimport com.wm.app.b2b.server.InvokeState;%0Aimport com.wm.app.b2b.server.Service;%0Aimport com.wm.data.IData;%0Aimport com.wm.data.IDataUtil;%0Aimport com.wm.lang.ns.NSName;%0Aimport permafrost.tundra.server.ServerThreadFactory;%0Aimport permafrost.tundra.server.service.CallableService;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.Executors;%0Aimport java.util.concurrent.TimeUnit;%0A%0A/**%0A * A collection of convenience methods for invoking services.%0A */%0Apublic class DeferHelper %7B%0A    /**%0A     * The amount of time to wait for all queued deferred services to finish executing before shutdown.%0A     */%0A    private static final long SHUTDOWN_TIMEOUT_MINUTES = 5;%0A%0A    /**%0A     * Disallow instantiation of this class.%0A     */%0A    private DeferHelper() %7B%7D%0A%0A    /**%0A     * Initialization on demand holder idiom.%0A     */%0A    private static class Holder %7B%0A        /**%0A         * Singleton instance of executor service for invoking deferred services.%0A         */%0A        private static final ExecutorService DEFER_EXECUTOR = Executors.newSingleThreadExecutor(new ServerThreadFactory(%22Tundra/Defer Thread%22, InvokeState.getCurrentState()));%0A    %7D%0A%0A    /**%0A     * Queues the given service and input pipeline for execution later by a dedicated single thread.%0A     *%0A     * @param service   The service to be executed some time later.%0A     * @param pipeline  The input pipeline for the service.%0A     */%0A    public static void defer(String service, IData pipeline) %7B%0A        defer(NSName.create(service), pipeline);%0A    %7D%0A%0A    /**%0A     * Queues the given service and input pipeline for execution later by a dedicated single thread.%0A     *%0A     * @param service   The service to be executed some time later.%0A     * @param pipeline  The input pipeline for the service.%0A     */%0A    public static void defer(NSName service, IData pipeline) %7B%0A        Holder.DEFER_EXECUTOR.submit(new CallableService(service, Service.getSession(), IDataUtil.clone(pipeline)));%0A    %7D%0A%0A    /**%0A     * Shuts down the thread pool used for executing deferred services.%0A     */%0A    public static void shutdown() %7B%0A        try %7B%0A            Holder.DEFER_EXECUTOR.shutdown();%0A            Holder.DEFER_EXECUTOR.awaitTermination(SHUTDOWN_TIMEOUT_MINUTES, TimeUnit.MINUTES);%0A        %7D catch(InterruptedException ex) %7B%0A            // ignore interruption to this thread%0A        %7D finally %7B%0A            Holder.DEFER_EXECUTOR.shutdownNow();%0A        %7D%0A    %7D%0A%7D%0A

Add DeferHelper class for deferred service invocations