/* * Copyright (c) 2008-2017, Hazelcast, Inc. 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 com.hazelcast.scheduledexecutor; import com.hazelcast.config.Config; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstanceAware; import com.hazelcast.core.IMap; import com.hazelcast.core.Member; import com.hazelcast.core.PartitionAware; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.TestHazelcastInstanceFactory; import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import static java.lang.System.currentTimeMillis; import static java.lang.Thread.sleep; /** * Common methods used in ScheduledExecutorService tests */ public class ScheduledExecutorServiceTestSupport extends HazelcastTestSupport { public IScheduledExecutorService getScheduledExecutor(HazelcastInstance[] instances, String name) { return instances[0].getScheduledExecutorService(name); } public int getPartitionIdFromPartitionAwareTask(HazelcastInstance instance, PartitionAware task) { return instance.getPartitionService().getPartition(task.getPartitionKey()).getPartitionId(); } public HazelcastInstance[] createClusterWithCount(int count) { return createClusterWithCount(count, new Config()); } public HazelcastInstance[] createClusterWithCount(int count, Config config) { TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(); HazelcastInstance[] instances = factory.newInstances(config, count); waitAllForSafeState(instances); return instances; } public int countScheduledTasksOn(IScheduledExecutorService scheduledExecutorService) { Map<Member, List<IScheduledFuture<Double>>> allScheduled = scheduledExecutorService.getAllScheduledFutures(); int total = 0; for (Member member : allScheduled.keySet()) { total += allScheduled.get(member).size(); } return total; } static class StatefulRunnableTask implements Runnable, Serializable, HazelcastInstanceAware, StatefulTask<String, Integer> { final String latchName; final String runCounterName; final String loadCounterName; int status = 0; transient HazelcastInstance instance; StatefulRunnableTask(String runsCountLatchName, String runCounterName, String loadCounterName) { this.latchName = runsCountLatchName; this.runCounterName = runCounterName; this.loadCounterName = loadCounterName; } @Override public void run() { status++; instance.getAtomicLong(runCounterName).set(status); instance.getCountDownLatch(latchName).countDown(); } @Override public void load(Map<String, Integer> snapshot) { status = snapshot.get("status"); instance.getAtomicLong(loadCounterName).incrementAndGet(); } @Override public void save(Map<String, Integer> snapshot) { snapshot.put("status", status); } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class ICountdownLatchCallableTask implements Callable<Double>, Serializable, HazelcastInstanceAware { final String runLatchName; final int sleepPeriod; transient HazelcastInstance instance; ICountdownLatchCallableTask(String runLatchName, int sleepPeriod) { this.runLatchName = runLatchName; this.sleepPeriod = sleepPeriod; } @Override public Double call() { try { sleep(sleepPeriod); } catch (InterruptedException e) { Thread.interrupted(); } instance.getCountDownLatch(runLatchName).countDown(); return 77 * 2.2; } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class ICountdownLatchMapIncrementCallableTask implements Runnable, Serializable, HazelcastInstanceAware { final String runLatchName; final String runEntryCounterName; final String mapName; transient HazelcastInstance instance; ICountdownLatchMapIncrementCallableTask(String mapName, String runEntryCounterName, String runLatchName) { this.mapName = mapName; this.runEntryCounterName = runEntryCounterName; this.runLatchName = runLatchName; } @Override public void run() { instance.getAtomicLong(runEntryCounterName).incrementAndGet(); IMap<String, Integer> map = instance.getMap(mapName); for (int i = 0; i < 100000; i++) { if (map.get(String.valueOf(i)) == i) { map.put(String.valueOf(i), i + 1); } } instance.getCountDownLatch(runLatchName).countDown(); } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class ICountdownLatchRunnableTask implements Runnable, Serializable, HazelcastInstanceAware { final String[] runsCounterlatchNames; transient HazelcastInstance instance; ICountdownLatchRunnableTask(String... runsCounterlatchNames) { this.runsCounterlatchNames = runsCounterlatchNames; } @Override public void run() { for (String runsCounterLatchName : runsCounterlatchNames) { instance.getCountDownLatch(runsCounterLatchName).countDown(); } } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class HotLoopBusyTask implements Runnable, HazelcastInstanceAware, Serializable { private final String runFinishedLatchName; private transient HazelcastInstance instance; HotLoopBusyTask(String runFinishedLatchName) { this.runFinishedLatchName = runFinishedLatchName; } @Override public void run() { long start = currentTimeMillis(); while (true) { try { sleep(5000); if (currentTimeMillis() - start >= 30000) { instance.getCountDownLatch(runFinishedLatchName).countDown(); break; } } catch (InterruptedException e) { // ignore } } } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class PlainCallableTask implements Callable<Double>, Serializable { private int delta = 0; public PlainCallableTask() { } public PlainCallableTask(int delta) { this.delta = delta; } @Override public Double call() throws Exception { return 5 * 5.0 + delta; } } static class EchoTask implements Runnable, Serializable { public EchoTask() { } @Override public void run() { System.out.println("Echo ...cho ...oo ..o"); } } static class ErroneousCallableTask implements Callable<Double>, Serializable, HazelcastInstanceAware { private String completionLatchName; private transient HazelcastInstance instance; ErroneousCallableTask() { } ErroneousCallableTask(String completionLatchName) { this.completionLatchName = completionLatchName; } @Override public Double call() throws Exception { try { throw new IllegalStateException("Erroneous task"); } finally { if (completionLatchName != null) { instance.getCountDownLatch(completionLatchName).countDown(); } } } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } static class PlainPartitionAwareCallableTask implements Callable<Double>, Serializable, PartitionAware<String> { @Override public Double call() throws Exception { return 5 * 5.0; } @Override public String getPartitionKey() { return "TestKey"; } } static class PlainPartitionAwareRunnableTask implements Runnable, Serializable, PartitionAware<String>, HazelcastInstanceAware { private final String latchName; private transient HazelcastInstance instance; public PlainPartitionAwareRunnableTask(String latchName) { this.latchName = latchName; } @Override public void run() { this.instance.getCountDownLatch(latchName).countDown(); } @Override public String getPartitionKey() { return "TestKey"; } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.instance = hazelcastInstance; } } public static class HazelcastInstanceAwareRunnable implements Callable<Boolean>, HazelcastInstanceAware, Serializable, NamedTask { private transient volatile HazelcastInstance instance; private final String name; public HazelcastInstanceAwareRunnable(String name) { this.name = name; } @Override public void setHazelcastInstance(final HazelcastInstance instance) { this.instance = instance; } @Override public String getName() { return name; } @Override public Boolean call() { return (instance != null); } } }