/*
* Copyright (C) 2011 Red Hat, Inc. and/or its affiliates.
*
* 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.jboss.errai.bus.tests;
import junit.framework.TestCase;
import org.jboss.errai.common.client.util.TimeUnit;
import org.jboss.errai.bus.server.async.scheduling.PooledExecutorService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
public class PooledExecuterServiceTests extends TestCase {
class ConcurrentTestObj {
public final List<Long> list = Collections.synchronizedList(new ArrayList<Long>(10000));
public void add(Long longVal) {
synchronized (list) {
list.add(longVal);
}
}
public Long getLast() {
synchronized (list) {
if (list.isEmpty()) return 1l;
else return list.get(list.size() - 1);
}
}
public Long getSum() {
synchronized (list) {
long sum = 0;
for (Long l : list) {
sum += l;
}
return sum;
}
}
}
private ConcurrentTestObj generateBaseLine() {
ConcurrentTestObj baseline = new ConcurrentTestObj();
for (int i = 0; i < 1000; i++) {
baseline.add(baseline.getLast() + 2);
}
return baseline;
}
private long startTime1 = 0;
private long startTime2 = 0;
private long timer1 = 0;
private final Object timerLock1 = new Object();
private long timer2 = 0;
private final Object timerLock2 = new Object();
public void incrementTimer1(long amt) {
synchronized (timerLock1) {
timer1 += amt;
}
}
public void incrementTimer2(long amt) {
synchronized (timerLock2) {
timer2 += amt;
}
}
double average1 = 0;
double average2 = 0;
boolean failTest = false;
Throwable failure;
public void notestHighLoad() throws InterruptedException {
PooledExecutorService svc = new PooledExecutorService(10, PooledExecutorService.SaturationPolicy.CallerRuns);
svc.start();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(100);
executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
}
});
final ConcurrentTestObj baseline = generateBaseLine();
System.out.println("Generated baseline ...");
for (int x = 0; x < 30; x++) {
final ConcurrentTestObj test = new ConcurrentTestObj();
long tm = System.nanoTime();
svc.execute(new Runnable() {
public void run() {
startTime1 = System.nanoTime();
}
});
for (int i = 0; i < 1000; i++) {
svc.execute(new Runnable() {
public void run() {
synchronized (test) {
test.add(test.getLast() + 2);
}
}
});
}
System.out.println("(A) = " + (tm = (System.nanoTime() - tm)));
svc.execute(new Runnable() {
public void run() {
incrementTimer1(System.nanoTime() - startTime1);
}
});
average1 += tm;
final ConcurrentTestObj test2 = new ConcurrentTestObj();
tm = System.nanoTime();
executor.execute(new Runnable() {
public void run() {
startTime2 = System.nanoTime();
}
});
for (int i = 0; i < 1000; i++) {
executor.execute(new Runnable() {
public void run() {
synchronized (test2) {
test2.add(test2.getLast() + 2);
}
}
});
}
System.out.println("(B) = " + (tm = (System.nanoTime() - tm)));
executor.execute(new Runnable() {
public void run() {
incrementTimer2(System.nanoTime() - startTime2);
}
});
average2 += tm;
svc.execute(new Runnable() {
public void run() {
try {
System.out.println("CHECK");
assertEquals(baseline.getSum(), test.getSum());
System.out.println("(A) GOOD!");
}
catch (Throwable e) {
failure = e;
failTest = true;
System.out.println("(A) ERR");
e.printStackTrace();
}
}
});
if (failTest) {
fail("potential thread-racing condition detected in scheduler");
}
executor.execute(new Runnable() {
public void run() {
try {
System.out.println("CHECK2");
assertEquals(baseline.getSum(), test2.getSum());
System.out.println("(B) GOOD!");
}
catch (Throwable e) {
System.out.println("(B) ERR");
e.printStackTrace();
}
}
});
}
System.out.println("Schedule");
svc.execute(new Runnable() {
public void run() {
System.out.println("Average Scheduling Perf (A):" + (average1 / 100));
System.out.println("Average Run Perf (A):" + timer1);
}
});
System.out.println("Schedule2");
executor.execute(new Runnable() {
public void run() {
System.out.println("Average Scheduling Perf (B):" + (average2 / 100));
System.out.println("Average Run Perf (B):" + timer2);
}
});
}
public void testExecutorServiceStress() {
PooledExecutorService svc = new PooledExecutorService(10, PooledExecutorService.SaturationPolicy.CallerRuns);
svc.start();
int size = 50;
int seconds = 20;
final int[] vals = new int[size];
final int[] vals2 = new int[size];
for (int i = 0; i < size; i++) {
final int x = i;
svc.scheduleRepeating(new Runnable() {
public void run() {
vals[x]++;
}
}, TimeUnit.MILLISECONDS, 0, 1);
}
boolean loop = true;
int loops = 0;
try {
do {
Thread.sleep(1000);
System.out.println("vals=" + Arrays.toString(vals));
if (loops != 0)
for (int i = 0; i < vals.length; i++) {
assertTrue(vals[i] > vals2[i]);
}
for (int i = 0; i < vals.length; i++) {
vals2[i] = vals[i];
}
if (++loops == seconds) loop = false;
} while (loop);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}