public void stop() { if (log.isDebugEnabled()) log.debug("Stopping poll for {} (using {})", new Object[] {entity, this}); if (!started) { throw new IllegalStateException(String.format("Attempt to stop poller %s of entity %s when not running", this, entity)); } started = false; for (Task<?> task : oneOffTasks) { if (task != null) task.cancel(true); } for (ScheduledTask task : tasks) { if (task != null) task.cancel(); } oneOffTasks.clear(); tasks.clear(); }
@Override public void stopReadOnly() { readOnlyRunning = false; if (readOnlyTask!=null) { LOG.debug("Stopping read-only rebinding ("+this+"), mgmt "+managementContext.getManagementNodeId()); readOnlyTask.cancel(true); readOnlyTask.blockUntilEnded(); boolean reallyEnded = Tasks.blockUntilInternalTasksEnded(readOnlyTask, Duration.TEN_SECONDS); if (!reallyEnded) { LOG.warn("Rebind (read-only) tasks took too long to die after interrupt (ignoring): "+readOnlyTask); } readOnlyTask = null; LOG.debug("Stopped read-only rebinding ("+this+"), mgmt "+managementContext.getManagementNodeId()); } }
@Test public void testCanCancelScheduledTask() throws Exception { final int period = 1; final long checkPeriod = 250; final List<Long> timestamps = Collections.synchronizedList(Lists.<Long>newArrayList()); Callable<Task<?>> taskFactory = new Callable<Task<?>>() { @Override public Task<?> call() { return new BasicTask<Void>(new Runnable() { @Override public void run() { timestamps.add(System.currentTimeMillis()); }}); }}; ScheduledTask t = new ScheduledTask(taskFactory).period(period); em.submit(t); t.cancel(); long cancelTime = System.currentTimeMillis(); int countImmediatelyAfterCancel = timestamps.size(); Thread.sleep(checkPeriod); int countWellAfterCancel = timestamps.size(); // should have at most 1 more execution after cancel log.info("testCanCancelScheduledTask saw "+countImmediatelyAfterCancel+" then cancel then "+countWellAfterCancel+" total"); assertTrue(countWellAfterCancel - countImmediatelyAfterCancel <= 2, "timestamps="+timestamps+"; cancelTime="+cancelTime); }
void stop(Duration timeout, Duration graceTimeoutForSubsequentOperations) { synchronized (startStopMutex) { state = ListenerState.STOPPING; try { if (scheduledTask != null) { CountdownTimer expiry = timeout.countdownTimer(); try { scheduledTask.cancel(false); waitForPendingComplete(expiry.getDurationRemaining().lowerBound(Duration.ZERO).add(graceTimeoutForSubsequentOperations), true); } catch (Exception e) { throw Exceptions.propagate(e); } scheduledTask.blockUntilEnded(expiry.getDurationRemaining().lowerBound(Duration.ZERO).add(graceTimeoutForSubsequentOperations)); scheduledTask.cancel(true); boolean reallyEnded = Tasks.blockUntilInternalTasksEnded(scheduledTask, expiry.getDurationRemaining().lowerBound(Duration.ZERO).add(graceTimeoutForSubsequentOperations)); if (!reallyEnded) { LOG.warn("Persistence tasks took too long to terminate, when stopping persistence, although pending changes were persisted (ignoring): "+scheduledTask); } scheduledTask = null; } // Discard all state that was waiting to be persisted synchronized (this) { deltaCollector = new DeltaCollector(); } } finally { state = ListenerState.STOPPED; } } }
t.cancel(true); t.blockUntilEnded();
t.cancel(true); t.blockUntilEnded();