/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.tasks.test;
import java.util.concurrent.atomic.AtomicReference;
import divconq.hub.Hub;
import divconq.lang.op.OperationCallback;
import divconq.lang.op.OperationContext;
import divconq.lang.op.OperationObserver;
import divconq.scheduler.ISchedule;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;
import divconq.work.ISynchronousWork;
import divconq.work.IWork;
import divconq.work.Task;
import divconq.work.TaskCountDownCallback;
import divconq.work.TaskRun;
import divconq.work.WorkBucket;
import divconq.work.WorkPool;
public class TestBucketMaxSize implements IWork {
@Override
public void run(final TaskRun testrunner) {
testrunner.info("TestBucketMaxSize main attempting to start in Bucket: " + testrunner.getTask().getBucket());
RecordStruct params = testrunner.getTask().getParams();
int launch = 21;
if (params != null) {
launch = (int) params.getFieldAsInteger("LaunchCount", launch);
}
WorkPool wp = Hub.instance.getWorkPool();
final WorkBucket bucket = new WorkBucket();
bucket.setName("MaxSizeTest");
bucket.setMaxSize(4); // run only 4 at a time
//bucket.setTrace(true);
wp.addBucket(bucket);
final AtomicReference<ISchedule> reportschedule = new AtomicReference<>();
// when all the tasks are done, here is what to do
final TaskCountDownCallback cntdwn = new TaskCountDownCallback(launch, new OperationCallback() {
@Override
public void callback() {
// note this task id should be the same as main
testrunner.info("TestBucketMaxSize main attempting to cancel reporter in Bucket: " + testrunner.getTask().getBucket());
// stop reporting
reportschedule.get().cancel();
// note this task id should be the same as main
testrunner.info("TestBucketMaxSize main attempting to cleanup in Bucket: " + testrunner.getTask().getBucket());
// the bucket is for testing only, remove it
Hub.instance.getWorkPool().removeBucket(bucket.getName());
// note this task id should be the same as main
testrunner.info("TestBucketMaxSize completed!");
// mark this TEST task as complete
testrunner.complete();
}
});
// launch the (sub) tasks
for (int i = 0; i < launch; i++) {
Task task = new Task()
.withTitle("Greeting Carl " + i)
.withParams(new RecordStruct(new FieldStruct("Greet", "Carl")))
.withTimeout(5) // allow for the fact it is "slow" and "dumb" (won't talk to log to stay alive) and give 5 seconds to complete
.withContext(
OperationContext.get()
.toBuilder()
.withNewOpId() // same user, logging, etc as test task, just use new op ids (it is fine to have same op id, this is just an example of how to use another op id)
.toOperationContext()
)
.withBucket(bucket.getName())
.withWork(SlowGreetWork.class);
Hub.instance.getWorkPool().submit(task, new OperationObserver() {
@Override
public void completed(OperationContext or) {
int left = cntdwn.countDown();
// the message, when printed, should be in the context of the greeter task, not in our task
if (left == 0)
or.info("I was the last greeter!");
}
});
}
// create a task that shows the TEST bucket status every second
Task reporttask = new Task()
.withContext(
OperationContext.get()
.toBuilder()
.withNewOpId() // same user, logging, etc as test task, just use new task ids
.toOperationContext()
)
.withWork(new ISynchronousWork() {
@Override
public void run(TaskRun run) {
run.info("TestBucketMaxSize reporter attempting to run in Bucket: " + run.getTask().getBucket());
// by logging on testrunner we are keeping it active - without this it would likely timeout
testrunner.info("REPORT - In Progress: " + bucket.inprogress() + " - Backlog: " + bucket.backlog());
}
});
reportschedule.set(Hub.instance.getScheduler().runEvery(reporttask, 1));
}
}