this.timeoutExecutor = new TimeoutExecutorThread<>(this, threadGroup);
/** * Add a chore procedure to the executor * @param chore the chore to add */ public void addChore(ProcedureInMemoryChore<TEnvironment> chore) { chore.setState(ProcedureState.WAITING_TIMEOUT); timeoutExecutor.add(chore); }
@VisibleForTesting public void join() { assert !isRunning() : "expected not running"; // stop the timeout executor timeoutExecutor.awaitTermination(); // stop the worker threads for (WorkerThread worker: workerThreads) { worker.awaitTermination(); } // Destroy the Thread Group for the executors // TODO: Fix. #join is not place to destroy resources. try { threadGroup.destroy(); } catch (IllegalThreadStateException e) { LOG.error("ThreadGroup {} contains running threads; {}: See STDOUT", this.threadGroup, e.getMessage()); // This dumps list of threads on STDOUT. this.threadGroup.list(); } // reset the in-memory state for testing completed.clear(); rollbackStack.clear(); procedures.clear(); nonceKeysToProcIdsMap.clear(); scheduler.clear(); lastProcId.set(-1); }
@Override public void run() { while (executor.isRunning()) { final DelayedWithTimeout task = DelayedUtil.takeWithoutInterrupt(queue); if (task == null || task == DelayedUtil.DELAYED_POISON) { // the executor may be shutting down, // and the task is just the shutdown request continue; } LOG.trace("Executing {}", task); // execute the task if (task instanceof InlineChore) { execInlineChore((InlineChore) task); } else if (task instanceof DelayedProcedure) { execDelayedProcedure((DelayedProcedure<TEnvironment>) task); } else { LOG.error("CODE-BUG unknown timeout task type {}", task); } } }
/** * Start the workers. */ public void startWorkers() throws IOException { if (!running.compareAndSet(false, true)) { LOG.warn("Already running"); return; } // Start the executors. Here we must have the lastProcId set. LOG.trace("Start workers {}", workerThreads.size()); timeoutExecutor.start(); for (WorkerThread worker: workerThreads) { worker.start(); } // Internal chores timeoutExecutor.add(new WorkerMonitor()); // Add completed cleaner chore addChore(new CompletedProcedureCleaner<>(conf, store, procExecutionLock, completed, nonceKeysToProcIdsMap)); }
private void execDelayedProcedure(DelayedProcedure<TEnvironment> delayed) { // TODO: treat this as a normal procedure, add it to the scheduler and // let one of the workers handle it. // Today we consider ProcedureInMemoryChore as InlineChores Procedure<TEnvironment> procedure = delayed.getObject(); if (procedure instanceof ProcedureInMemoryChore) { executeInMemoryChore((ProcedureInMemoryChore<TEnvironment>) procedure); // if the procedure is in a waiting state again, put it back in the queue procedure.updateTimestamp(); if (procedure.isWaiting()) { delayed.setTimeout(procedure.getTimeoutTimestamp()); queue.add(delayed); } } else { executeTimedoutProcedure(procedure); } }
timeoutExecutor = new TimeoutExecutorThread(this, threadGroup); timeoutExecutor.start(); for (WorkerThread worker: workerThreads) { worker.start(); timeoutExecutor.add(new WorkerMonitor());
if (timeoutExecutor.remove(procedure)) { LOG.debug("removed procedure {} from timeoutExecutor", procedure); timeoutExecutor.executeTimedoutProcedure(procedure);
public TimeoutExecutorThread(ProcedureExecutor<TEnvironment> executor, ThreadGroup group) { super(group, "ProcExecTimeout"); setDaemon(true); this.executor = executor; }
public void stop() { if (!running.getAndSet(false)) { return; } LOG.info("Stopping"); scheduler.stop(); timeoutExecutor.sendStopSignal(); }
/** * Remove a chore procedure from the executor * @param chore the chore to remove * @return whether the chore is removed, or it will be removed later */ public boolean removeChore(ProcedureInMemoryChore<TEnvironment> chore) { chore.setState(ProcedureState.SUCCESS); return timeoutExecutor.remove(chore); }
@Override public void run() { while (executor.isRunning()) { final DelayedWithTimeout task = DelayedUtil.takeWithoutInterrupt(queue); if (task == null || task == DelayedUtil.DELAYED_POISON) { // the executor may be shutting down, // and the task is just the shutdown request continue; } LOG.trace("Executing {}", task); // execute the task if (task instanceof InlineChore) { execInlineChore((InlineChore) task); } else if (task instanceof DelayedProcedure) { execDelayedProcedure((DelayedProcedure<TEnvironment>) task); } else { LOG.error("CODE-BUG unknown timeout task type {}", task); } } }
private void execDelayedProcedure(DelayedProcedure<TEnvironment> delayed) { // TODO: treat this as a normal procedure, add it to the scheduler and // let one of the workers handle it. // Today we consider ProcedureInMemoryChore as InlineChores Procedure<TEnvironment> procedure = delayed.getObject(); if (procedure instanceof ProcedureInMemoryChore) { executeInMemoryChore((ProcedureInMemoryChore<TEnvironment>) procedure); // if the procedure is in a waiting state again, put it back in the queue procedure.updateTimestamp(); if (procedure.isWaiting()) { delayed.setTimeout(procedure.getTimeoutTimestamp()); queue.add(delayed); } } else { executeTimedoutProcedure(procedure); } }
if (timeoutExecutor.remove(procedure)) { LOG.debug("removed procedure {} from timeoutExecutor", procedure); timeoutExecutor.executeTimedoutProcedure(procedure);
public TimeoutExecutorThread(ProcedureExecutor<?> executor, ThreadGroup group) { super(group, "ProcExecTimeout"); setDaemon(true); this.executor = executor; }
public void stop() { if (!running.getAndSet(false)) { return; } LOG.info("Stopping"); scheduler.stop(); timeoutExecutor.sendStopSignal(); }
/** * Remove a chore procedure from the executor * @param chore the chore to remove * @return whether the chore is removed, or it will be removed later */ public boolean removeChore(ProcedureInMemoryChore<TEnvironment> chore) { chore.setState(ProcedureState.SUCCESS); return timeoutExecutor.remove(chore); }
private void execInlineChore(InlineChore chore) { chore.run(); add(chore); }
@Override public void run() { while (executor.isRunning()) { final DelayedWithTimeout task = DelayedUtil.takeWithoutInterrupt(queue); if (task == null || task == DelayedUtil.DELAYED_POISON) { // the executor may be shutting down, // and the task is just the shutdown request continue; } LOG.trace("Executing {}", task); // execute the task if (task instanceof InlineChore) { execInlineChore((InlineChore) task); } else if (task instanceof DelayedProcedure) { execDelayedProcedure((DelayedProcedure) task); } else { LOG.error("CODE-BUG unknown timeout task type {}", task); } } }