/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
package org.terracotta.quartz.tests;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.terracotta.toolkit.concurrent.ToolkitBarrier;
import org.terracotta.toolkit.concurrent.atomic.ToolkitAtomicLong;
import com.tc.util.concurrent.ThreadUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
public class SimpleOrderingClient extends ClientBase {
public static final int NODE_COUNT = 5;
public static ToolkitAtomicLong count;
private final ToolkitBarrier barrier;
public SimpleOrderingClient(String[] args) {
super(args);
count = getClusteringToolkit().getAtomicLong("count");
barrier = getClusteringToolkit().getBarrier("barrier", NODE_COUNT);
}
@Override
public void addSchedulerProperties(Properties properties) {
properties.setProperty(StdSchedulerFactory.PROP_SCHED_IDLE_WAIT_TIME, "1000");
}
@Override
protected boolean isStartingScheduler() {
return false;
}
@Override
protected void test(Scheduler sched) throws Throwable {
final long NUM = 25;
int index = barrier.await();
final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
sched.getListenerManager().addJobListener(new JobListener() {
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
if (jobException != null) {
jobException.getUnderlyingException().printStackTrace();
error.set(jobException.getUnderlyingException());
}
}
public void jobToBeExecuted(JobExecutionContext context) {
//
}
public void jobExecutionVetoed(JobExecutionContext context) {
//
}
public String getName() {
return "listener";
}
}, EverythingMatcher.allJobs());
sched.start();
barrier.await();
if (index == 0) {
final long startBase = System.currentTimeMillis() + 10000L;
List<Long> numbers = new ArrayList<Long>();
for (long i = 0; i < NUM; i++) {
numbers.add(i);
}
Collections.shuffle(numbers);
for (long i : numbers) {
JobDetail jobDetail = new JobDetailImpl("myJob" + i, null, TestJob.class);
jobDetail.getJobDataMap().put("number", i);
long startTime = startBase + (5000L * i);
Trigger trigger = new SimpleTriggerImpl("trigger" + i, null, new Date(startTime), null, 0, 0L);
System.err.println("Scheduling job " + i + " to run at " + new Date(startTime));
sched.scheduleJob(jobDetail, trigger);
}
}
barrier.await();
if (index == 0) {
int val;
while ((val = count.intValue()) != NUM) {
ThreadUtil.reallySleep(1000L);
System.err.println("counter: " + val);
}
}
barrier.await();
sched.shutdown();
if (error.get() != null) { throw error.get(); }
}
public static class TestJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
long expect = context.getJobDetail().getJobDataMap().getLong("number");
System.err.println("[" + new Date() + "]: expecting " + expect);
long actual = count.getAndIncrement();
if (expect != actual) { throw new JobExecutionException(new AssertionError(expect + " != " + actual)); }
}
}
}