Class ConseqExecutor

    • Method Detail

      • newInstance

        @Nonnull
        public static ConseqExecutor newInstance()
        Returns:
        conseq executor with default concurrency
      • newInstance

        @Nonnull
        public static ConseqExecutor newInstance​(int concurrency)
        Parameters:
        concurrency - max number of tasks that can be run in parallel by the returned executor instance. This is set as the max capacity of the workerThreadPool
        Returns:
        conseq executor with given concurrency
      • from

        public static ConseqExecutor from​(ThreadPoolExecutor workerThreadPool)
        Parameters:
        workerThreadPool - the worker thread pool that facilitates the overall async execution, independent of the submitted tasks.
        Returns:
        new ConseqExecutor instance backed by the specified workerThreadPool
      • submit

        public <T> CompletableFuture<T> submit​(@NonNull
                                               @NonNull Callable<T> task,
                                               @NonNull
                                               @NonNull Object sequenceKey)
        Tasks of different sequence keys execute in parallel, pending thread availability from the backing workerThreadPool.

        Sequential execution of tasks under the same/equal sequence key is achieved by linearly chaining/queuing the task/work stages of the same key, leveraging the CompletableFuture API.

        A ConcurrentMap is employed to keep track of each sequence key's pending tasks status. Each map entry represents an active sequential executor in-service for all the tasks under the same sequence key; the entry's value is to hold the most recently added task as the tail of the FIFO task queue of the active executor. With this executor map, an active executor can be located by its sequence key so that a subsequent task of the same key can be queued/chained behind the previous task. If no active executor exists in the map for the submitted task's sequence key, a new entry/executor will be created. Before added to the tail of the task queue, each task will be converted to a new corresponding work stage (of type CompletableFuture). If there already exists an entry/work stage of the same sequence key in the map, the current work stage will be chained to execute behind the existing work stage and replace the existing stage as the tail of the task queue in the map entry. This new work stage will not start executing before the previous stage completes, and will have to finish executing before the next task's work stage can start executing. Such linear progression of the work tasks/stages ensures the sequential-ness of task execution under the same sequence key.

        A separate administrative task/stage is triggered to run at the completion of each work task/stage. Under the same sequence key, this admin task will locate the executor entry in the map, and remove the entry if its work stage is complete. Otherwise, if the work stage is not complete, the admin task does nothing; the incomplete work stage stays in the map under the same sequence key, ready to be trailed by the next work stage. This administration ensures that every executor entry ever put on the map is eventually cleaned up and removed as long as every work stage runs to complete. Although always chained after the completion of a work stage, the admin task/stage is never added to the task work queue on the executor map and has no effect on the overall sequential-ness of the work stage executions.

        Specified by:
        submit in interface SequentialExecutor
        Type Parameters:
        T - the type of the task's result
        Parameters:
        task - the task to be called asynchronously with proper sequence
        sequenceKey - the key under which this task should be sequenced
        Returns:
        future result of the task, not downcast-able from the basic Future interface.
      • shutdown

        public void shutdown()
        Description copied from interface: Terminable
        Nonblocking, initiates an orderly shutdown of all managed thread resources. Previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
        Specified by:
        shutdown in interface Terminable
      • isTerminated

        public boolean isTerminated()
        Description copied from interface: Terminable
        Nonblocking
        Specified by:
        isTerminated in interface Terminable
        Returns:
        true if all tasks of all managed executors have completed following shut down. Note that isTerminated is never true unless shutdown was called first.