public void flushTopology() { if (updateArrayActor != null) { updateArrayActor.flush(10, TimeUnit.SECONDS); } }
/** * It will wait the current execution (if there is one) to finish * but will not complete any further executions */ default int shutdownNow() { return shutdownNow(t -> { }); }
private void executePendingTasks() { do { //if there is no thread active and is not already dead then we run if (stateUpdater.compareAndSet(this, STATE_NOT_RUNNING, STATE_RUNNING)) { enter(); try { T task; //while the queue is not empty we process in order: //if requestedForcedShutdown==true than no new tasks will be drained from the tasks q. while (!requestedForcedShutdown && (task = tasks.poll()) != null) { doTask(task); } } finally { leave(); //set state back to not running if possible: shutdownNow could be called by doTask(task). //If a shutdown has happened there is no need to continue polling tasks if (!stateUpdater.compareAndSet(this, STATE_RUNNING, STATE_NOT_RUNNING)) { return; } } } else { return; } //we loop again based on tasks not being empty. Otherwise there is a window where the state is running, //but poll() has returned null, so a submitting thread will believe that it does not need re-execute. //this check fixes the issue } while (!tasks.isEmpty() && !requestedShutdown); }
/** To be used to flush an executor from a different thread. * WARNING: Do not call this within the executor. That would be stoopid ;) * * @param timeout * @param unit * @return */ default boolean flush(long timeout, TimeUnit unit) { CountDownLatch latch = new CountDownLatch(1); execute(latch::countDown); try { return latch.await(timeout, unit); } catch (Exception e) { return false; } }
protected void task(T command) { if (requestedShutdown) { logAddOnShutdown(); } //The shutdown process could finish right after the above check: shutdownNow can drain the remaining tasks tasks.add(command); //cache locally the state to avoid multiple volatile loads final int state = stateUpdater.get(this); if (state != STATE_RUNNING) { onAddedTaskIfNotRunning(state); } }
/** * Get an executor that always executes tasks in order. * * @return an ordered executor */ @Override public ArtemisExecutor getExecutor() { return new OrderedExecutor(parent); }
orderedExecutorFactory = new OrderedExecutorFactory(threadPool);
public static boolean flushExecutor(Executor executor) { return flushExecutor(executor, 30, TimeUnit.SECONDS); }
@SuppressWarnings("unchecked") private void updateArraysAndPairs(long time) { if (updateArrayActor == null) { // if for some reason we don't have an actor, just go straight internalUpdateArray(time); } else { updateArrayActor.act(time); } }
/** * It will shutdown and wait 30 seconds for timeout. */ public void shutdown() { shutdown(30, TimeUnit.SECONDS); }
@Override protected final void doTask(T task) { listener.onMessage(task); }
@Override public final void execute(Runnable run) { task(run); }
public final void act(T message) { task(message); }
private synchronized void setThreadPools() { if (threadPool != null) { return; } else if (useGlobalPools) { threadPool = ActiveMQClient.getGlobalThreadPool(); scheduledThreadPool = ActiveMQClient.getGlobalScheduledThreadPool(); } else { this.shutdownPool = true; ThreadFactory factory = AccessController.doPrivileged(new PrivilegedAction<ThreadFactory>() { @Override public ThreadFactory run() { return new ActiveMQThreadFactory("ActiveMQ-client-factory-threads-" + System.identityHashCode(this), true, ClientSessionFactoryImpl.class.getClassLoader()); } }); if (threadPoolMaxSize == -1) { threadPool = Executors.newCachedThreadPool(factory); } else { threadPool = new ActiveMQThreadPoolExecutor(0, threadPoolMaxSize, 60L, TimeUnit.SECONDS, factory); } factory = AccessController.doPrivileged(new PrivilegedAction<ThreadFactory>() { @Override public ThreadFactory run() { return new ActiveMQThreadFactory("ActiveMQ-client-factory-pinger-threads-" + System.identityHashCode(this), true, ClientSessionFactoryImpl.class.getClassLoader()); } }); scheduledThreadPool = Executors.newScheduledThreadPool(scheduledThreadPoolMaxSize, factory); } this.updateArrayActor = new Actor<>(threadPool, this::internalUpdateArray); }
/** * This will verify if the executor is flushed with no wait (or very minimal wait if not the {@link org.apache.activemq.artemis.utils.actors.OrderedExecutor} * @return */ default boolean isFlushed() { CountDownLatch latch = new CountDownLatch(1); Runnable runnable = new Runnable() { @Override public void run() { latch.countDown(); } }; execute(runnable); try { return latch.await(100, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { return false; } }
@Override public synchronized void initialize() throws ActiveMQException { if (state == STATE.INITIALIZED) return; synchronized (stateGuard) { if (state == STATE.CLOSING) throw new ActiveMQIllegalStateException(); try { state = STATE.INITIALIZED; latch = new CountDownLatch(1); setThreadPools(); topology.setExecutor(new OrderedExecutor(threadPool)); instantiateLoadBalancingPolicy(); if (discoveryGroupConfiguration != null) { discoveryGroup = createDiscoveryGroup(nodeID, discoveryGroupConfiguration); discoveryGroup.registerListener(this); discoveryGroup.start(); } } catch (Exception e) { state = null; throw ActiveMQClientMessageBundle.BUNDLE.failedToInitialiseSessionFactory(e); } } }
/** * It will shutdown and wait 30 seconds for timeout. */ public void shutdown() { shutdown(30, TimeUnit.SECONDS); }
@Override public void afterCommit(final Transaction tx1) { executor.execute(new Runnable() { @Override public void run() { if (!completeDelete) { cursorProvider.scheduleCleanup(); } } }); } });