/** * Runs the given task. Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * <p> * This method throws {@code IllegalStateException} if Engine does not have capacity to run the task. * Engine's capacity is specified by a {@value #MAX_CONCURRENT_PLANS} configuration property. Use * {@link EngineBuilder#setEngineProperty(String, Object)} to set this property. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * * @param task the task to run * @param planClass string that identifies a "class" of the Plan. Plan class ends up in a ParSeq * Trace and can be used to group traces into "classes" when traces are statistically analyzed. * @throws IllegalStateException */ public void run(final Task<?> task, final String planClass) { if (!tryRun(task, planClass)) { throw new IllegalStateException("Starting new plan rejected, exceeded limit of concurrent plans: " + _maxConcurrentPlans); } }
/** * Runs the given task if Engine has a capacity to start new plan as specified by * {@value #MAX_CONCURRENT_PLANS} configuration parameter. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * This method returns immediately and does not block. It returns {@code true} if Plan was successfully started. * @param task the task to run * @return true if Plan was started */ public boolean tryRun(final Task<?> task) { return tryRun(task, defaultPlanClass(task)); }
/** * Runs the given task if Engine has a capacity to start new plan as specified by * {@value #MAX_CONCURRENT_PLANS} configuration parameter within specified amount of time. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * If Engine does not have capacity to start the task, this method will block up to specified amount of * time waiting for other concurrently running Plans to complete. If there is no capacity to start the task * within specified amount of time this method will return false. It returns {@code true} if Plan was successfully started. * @param task the task to run * @param timeout amount of time to wait for Engine's capacity to run the task * @param unit * @return true if Plan was started within the given waiting time and the current thread has not * been {@linkplain Thread#interrupt interrupted}. */ public boolean tryRun(final Task<?> task, final long timeout, final TimeUnit unit) throws InterruptedException { return tryRun(task, defaultPlanClass(task), timeout, unit); }
@Test public void testTryRunWithinCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(0); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(counter::incrementAndGet); } for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i])); } assertTrue(awaitAll(tasks)); assertEquals(10, counter.get()); }
@Test public void testTimeBoundedTryRunWithinCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(0); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(counter::incrementAndGet); } for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], (i % 2 == 0) ? "evenPlan" : "oddPlan", 10, TimeUnit.MILLISECONDS)); } assertTrue(awaitAll(tasks)); assertEquals(10, counter.get()); }
@Test public void testTimeBoundedTryRunWithinCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(0); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(counter::incrementAndGet); } for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], 10, TimeUnit.MILLISECONDS)); } assertTrue(awaitAll(tasks)); assertEquals(10, counter.get()); }
@Test public void testTryRunWithinCapacity() throws InterruptedException { final AtomicInteger counter = new AtomicInteger(0); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(counter::incrementAndGet); } for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], (i % 2 == 0) ? "evenPlan" : "oddPlan")); } assertTrue(awaitAll(tasks)); assertEquals(10, counter.get()); }
@Test public void testTryRunOverCapacity() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(latch::await); } //within capacity for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i])); } assertFalse(_engine.tryRun(Task.action(() -> {}))); //release tasks latch.countDown(); //wait for tasks to finish assertTrue(awaitAll(tasks)); //should be unblocked assertTrue(_engine.tryRun(Task.action(() -> {}))); }
@Test public void testTimeBoundedTryRunOverCapacity() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(latch::await); } //within capacity for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], 10, TimeUnit.MILLISECONDS)); } assertFalse(_engine.tryRun(Task.action(() -> {}), 10, TimeUnit.MILLISECONDS)); //release tasks latch.countDown(); //wait for tasks to finish assertTrue(awaitAll(tasks)); //should be unblocked assertTrue(_engine.tryRun(Task.action(() -> {}), 10, TimeUnit.MILLISECONDS)); }
@Test public void testTryRunOverCapacity() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(latch::await); } //within capacity for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], (i % 2 == 0) ? "evenPlan" : "oddPlan")); } assertFalse(_engine.tryRun(Task.action(() -> {}), "oddPlan")); //release tasks latch.countDown(); //wait for tasks to finish assertTrue(awaitAll(tasks)); //should be unblocked assertTrue(_engine.tryRun(Task.action(() -> {}))); }
@Test public void testTimeBoundedTryRunOverCapacity() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); Task<?>[] tasks = new Task<?>[10]; for (int i = 0; i < 10; i++) { tasks[i] = Task.action(latch::await); } //within capacity for (int i = 0; i < 10; i++) { assertTrue(_engine.tryRun(tasks[i], (i % 2 == 0) ? "evenPlan" : "oddPlan", 10, TimeUnit.MILLISECONDS)); } assertFalse(_engine.tryRun(Task.action(() -> {}), "oddPlan", 10, TimeUnit.MILLISECONDS)); //release tasks latch.countDown(); //wait for tasks to finish assertTrue(awaitAll(tasks)); //should be unblocked assertTrue(_engine.tryRun(Task.action(() -> {}), "oddPlan", 10, TimeUnit.MILLISECONDS)); }
/** * Runs the given task. Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * <p> * This method throws {@code IllegalStateException} if Engine does not have capacity to run the task. * Engine's capacity is specified by a {@value #MAX_CONCURRENT_PLANS} configuration property. Use * {@link EngineBuilder#setEngineProperty(String, Object)} to set this property. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * * @param task the task to run * @param planClass string that identifies a "class" of the Plan. Plan class ends up in a ParSeq * Trace and can be used to group traces into "classes" when traces are statistically analyzed. * @throws IllegalStateException */ public void run(final Task<?> task, final String planClass) { if (!tryRun(task, planClass)) { throw new IllegalStateException("Starting new plan rejected, exceeded limit of concurrent plans: " + _maxConcurrentPlans); } }
/** * Runs the given task if Engine has a capacity to start new plan as specified by * {@value #MAX_CONCURRENT_PLANS} configuration parameter. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * This method returns immediately and does not block. It returns {@code true} if Plan was successfully started. * @param task the task to run * @return true if Plan was started */ public boolean tryRun(final Task<?> task) { return tryRun(task, defaultPlanClass(task)); }
/** * Runs the given task if Engine has a capacity to start new plan as specified by * {@value #MAX_CONCURRENT_PLANS} configuration parameter within specified amount of time. * For the sake of backwards compatibility default value for a {@value #MAX_CONCURRENT_PLANS} is * {@value #DEFUALT_MAX_CONCURRENT_PLANS} which essentially means "unbounded capacity". * Task passed in as a parameter becomes a root on a new Plan. * All tasks created and started as a consequence of a root task will belong to that plan and will share a Trace. * If Engine does not have capacity to start the task, this method will block up to specified amount of * time waiting for other concurrently running Plans to complete. If there is no capacity to start the task * within specified amount of time this method will return false. It returns {@code true} if Plan was successfully started. * @param task the task to run * @param timeout amount of time to wait for Engine's capacity to run the task * @param unit * @return true if Plan was started within the given waiting time and the current thread has not * been {@linkplain Thread#interrupt interrupted}. */ public boolean tryRun(final Task<?> task, final long timeout, final TimeUnit unit) throws InterruptedException { return tryRun(task, defaultPlanClass(task), timeout, unit); }