mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-21 05:05:31 +00:00
Merge branch 'master' into feature/procedure_wizard
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
/target
|
||||
www-test
|
||||
war
|
||||
build.log
|
||||
reporting.log
|
||||
.metadata
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sse.gwt.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
entryPointModules=com.sap.sse.gwt.test.TestSSE
|
||||
@@ -0,0 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
@@ -0,0 +1,9 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Test
|
||||
Bundle-SymbolicName: com.sap.sse.gwt.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: org.junit4;bundle-version="4.8.2"
|
||||
Fragment-Host: com.sap.sse.gwt;bundle-version="1.0.0.qualifier"
|
||||
@@ -0,0 +1,4 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sse.gwt.test</artifactId>
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>gwt-maven-plugin</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<configuration>
|
||||
<includes>**/AsyncActionsExecutorTest.java</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/AsyncActionsExecutorTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.7.0//EN" "http://gwtproject.org/doctype/2.7.0/gwt-module.dtd">
|
||||
<module>
|
||||
<inherits name="com.google.gwt.user.User" />
|
||||
<inherits name="com.sap.sse.gwt.SSESharedGWT"/>
|
||||
<inherits name="com.sap.sse.SSECommon"/>
|
||||
<source path="client"/>
|
||||
<source path="common"/>
|
||||
<source path="async"/>
|
||||
</module>
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package com.sap.sse.gwt.test.client;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.gwt.junit.client.GWTTestCase;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.async.AsyncAction;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
|
||||
/**
|
||||
* Some simple tests for the {@link AsyncActionsExecutor}.
|
||||
*
|
||||
* @author Simon Marcel Pamies
|
||||
*/
|
||||
public class AsyncActionsExecutorTest extends GWTTestCase {
|
||||
|
||||
private class AsyncActionWithExecutionCounter implements AsyncAction<Void> {
|
||||
private int executionCounter = 0;
|
||||
|
||||
private final boolean doSucceed;
|
||||
private final boolean doFail;
|
||||
|
||||
public AsyncActionWithExecutionCounter(boolean doSucceed, boolean doFail) {
|
||||
this.doFail = doFail;
|
||||
this.doSucceed = doSucceed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(AsyncCallback<Void> callback) {
|
||||
if (doSucceed) {
|
||||
callback.onSuccess(null);
|
||||
}
|
||||
if (doFail) {
|
||||
callback.onFailure(new RuntimeException());
|
||||
}
|
||||
executionCounter++;
|
||||
}
|
||||
|
||||
public int getExecutionCounter() {
|
||||
return executionCounter;
|
||||
}
|
||||
}
|
||||
|
||||
private AsyncCallback<Void> defaultCallback = new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
}
|
||||
};
|
||||
|
||||
private AsyncActionsExecutor executor;
|
||||
|
||||
@Test
|
||||
public void testThatANonTriggeringActionLeadsToPendingCall() {
|
||||
executor = new AsyncActionsExecutor(/*maxPendingCalls*/6, /*maxPendingCallsPerType*/5,
|
||||
/*durationAfterToResetQueue*/Duration.ONE_SECOND);
|
||||
// add a job that will never execute successfully
|
||||
AsyncAction<Void> nonTriggeringAction = new AsyncActionWithExecutionCounter(/*doSucceed*/false, /*doFail*/false);
|
||||
executor.execute(nonTriggeringAction, defaultCallback);
|
||||
// now the executor should have one pending action
|
||||
assertNotNull(executor.getNumberOfPendingActionsPerType(nonTriggeringAction.getClass().getName()));
|
||||
assertEquals(1, executor.getNumberOfPendingActionsPerType(nonTriggeringAction.getClass().getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTriggeringActionsLeadingToPendingQueue() {
|
||||
executor = new AsyncActionsExecutor(/*maxPendingCalls*/6, /*maxPendingCallsPerType*/6,
|
||||
/*durationAfterToResetQueue*/Duration.ONE_HOUR);
|
||||
// test completing jobs leading to empty pending queue
|
||||
AsyncAction<Void> successfulAction = new AsyncActionWithExecutionCounter(/*doSucceed*/true, /*doFail*/false);
|
||||
executor.execute(successfulAction, defaultCallback);
|
||||
assertEquals(0, executor.getNumberOfPendingActionsPerType(successfulAction.getClass().getName()));
|
||||
AsyncAction<Void> failingAction = new AsyncActionWithExecutionCounter(/*doSucceed*/false, /*doFail*/true);
|
||||
executor.execute(failingAction, defaultCallback);
|
||||
assertEquals(0, executor.getNumberOfPendingActionsPerType(failingAction.getClass().getName()));
|
||||
// test that max pending calls is being used
|
||||
AsyncAction<Void> nonTriggeringAction = new AsyncActionWithExecutionCounter(/*doSucceed*/false, /*doFail*/false);
|
||||
for (int i=0;i<=11;i++) {
|
||||
executor.execute(nonTriggeringAction, defaultCallback);
|
||||
}
|
||||
assertEquals(6, executor.getNumberOfPendingActions());
|
||||
assertEquals(6, executor.getNumberOfPendingActionsPerType(nonTriggeringAction.getClass().getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutomaticReleaseOfActionsImmediatelyAndAfterSomeTime() {
|
||||
executor = new AsyncActionsExecutor(/*maxPendingCalls*/6, /*maxPendingCallsPerType*/6,
|
||||
/*durationAfterToResetQueue*/Duration.ONE_SECOND.times(2));
|
||||
// execute action that does not get through but then retries
|
||||
AsyncActionWithExecutionCounter nonTriggeringAction = new AsyncActionWithExecutionCounter(/*doSucceed*/false, /*doFail*/false);
|
||||
assertEquals(0, nonTriggeringAction.getExecutionCounter());
|
||||
TimePoint startOfExecution = MillisecondsTimePoint.now();
|
||||
executor.execute(nonTriggeringAction, defaultCallback);
|
||||
assertEquals(1, nonTriggeringAction.getExecutionCounter());
|
||||
for (int i=0;i<=4;i++) {
|
||||
executor.execute(nonTriggeringAction, defaultCallback);
|
||||
}
|
||||
assertEquals(6, nonTriggeringAction.getExecutionCounter());
|
||||
assertEquals(6, executor.getNumberOfPendingActions());
|
||||
assertEquals(6, executor.getNumberOfPendingActionsPerType(nonTriggeringAction.getClass().getName()));
|
||||
// now the action should be retriggered - we can not use Thread.sleep() here as it is not
|
||||
// compilable by the GWT compiler. Using a hack to wait a little bit.
|
||||
while (MillisecondsTimePoint.now().minus(Duration.ONE_SECOND.times(3)).before(startOfExecution)) {
|
||||
}
|
||||
executor.execute(nonTriggeringAction, defaultCallback);
|
||||
assertEquals(7, nonTriggeringAction.getExecutionCounter());
|
||||
assertEquals(1, executor.getNumberOfPendingActions());
|
||||
assertEquals(1, executor.getNumberOfPendingActionsPerType(nonTriggeringAction.getClass().getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
return "com.sap.sse.gwt.test.TestSSE";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,21 +78,30 @@ public class AsyncActionsExecutor {
|
||||
|
||||
private final int maxPendingCalls;
|
||||
private final int maxPendingCallsPerType;
|
||||
private final Duration durationAfterToResetQueue;
|
||||
private final Map<String, Integer> actionsPerTypeCounter;
|
||||
private final Map<String, ExecutionJob<?>> lastRequestedActionsNotBeingSentOut;
|
||||
private final Map<String, TimePoint> timePointOfTypeLastBeingExecuted;
|
||||
|
||||
private int numPendingCalls = 0;
|
||||
private TimePoint timepointOfLastSuccessfulJobExecution = null;
|
||||
private TimePoint timePointOfFirstExecutorInit = null;
|
||||
|
||||
public AsyncActionsExecutor() {
|
||||
this(/*maxPendingCalls*/DEFAULT_MAX_PENDING_CALLS, /*maxPendingCallsPerType*/DEFAULT_MAX_PENDING_CALLS_PER_TYPE);
|
||||
this(/*maxPendingCalls*/DEFAULT_MAX_PENDING_CALLS, /*maxPendingCallsPerType*/DEFAULT_MAX_PENDING_CALLS_PER_TYPE,
|
||||
/*durationAfterToResetQueue*/DURATION_AFTER_TO_RESET_QUEUE);
|
||||
}
|
||||
|
||||
public AsyncActionsExecutor(int maxPendingCalls, int maxPendingCallsPerType) {
|
||||
public AsyncActionsExecutor(int maxPendingCalls, int maxPendingCallsPerType, Duration durationAfterToResetQueue) {
|
||||
if (maxPendingCalls < maxPendingCallsPerType) {
|
||||
throw new RuntimeException("The number of max pending calls can not be lower than the number of max pending calls per type.");
|
||||
}
|
||||
this.maxPendingCalls = maxPendingCalls;
|
||||
this.maxPendingCallsPerType = maxPendingCallsPerType;
|
||||
this.durationAfterToResetQueue = durationAfterToResetQueue;
|
||||
this.actionsPerTypeCounter = new HashMap<>();
|
||||
this.lastRequestedActionsNotBeingSentOut = new HashMap<>();
|
||||
this.timePointOfTypeLastBeingExecuted = new HashMap<>();
|
||||
this.timePointOfFirstExecutorInit = MillisecondsTimePoint.now(); // triggering duration to reset
|
||||
}
|
||||
|
||||
public <T> void execute(AsyncAction<T> action, AsyncCallback<T> callback) {
|
||||
@@ -103,6 +112,18 @@ public class AsyncActionsExecutor {
|
||||
execute(new ExecutionJob<T>(action, category, callback));
|
||||
}
|
||||
|
||||
public int getNumberOfPendingActionsPerType(String type) {
|
||||
int result = 0;
|
||||
if (actionsPerTypeCounter != null) {
|
||||
result = actionsPerTypeCounter.get(type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getNumberOfPendingActions() {
|
||||
return numPendingCalls;
|
||||
}
|
||||
|
||||
private void execute(ExecutionJob<?> job) {
|
||||
Integer numActionsOfType = actionsPerTypeCounter.get(job.getType());
|
||||
if (numActionsOfType == null) {
|
||||
@@ -110,8 +131,10 @@ public class AsyncActionsExecutor {
|
||||
}
|
||||
if (numPendingCalls >= maxPendingCalls || (numActionsOfType >= maxPendingCallsPerType)) {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
if (timepointOfLastSuccessfulJobExecution != null &&
|
||||
now.minus(DURATION_AFTER_TO_RESET_QUEUE).before(timepointOfLastSuccessfulJobExecution)) {
|
||||
TimePoint timePointToInspectForResetDecision = timePointOfTypeLastBeingExecuted.get(job.getType()) != null ?
|
||||
timePointOfTypeLastBeingExecuted.get(job.getType()) : timePointOfFirstExecutorInit;
|
||||
if (timePointToInspectForResetDecision != null &&
|
||||
now.minus(durationAfterToResetQueue).after(timePointToInspectForResetDecision)) {
|
||||
// reset the number of pending calls
|
||||
numPendingCalls = 0;
|
||||
// reset number of pending actions per type - 0 is fine as checkForEmptyCallQueue
|
||||
@@ -144,7 +167,7 @@ public class AsyncActionsExecutor {
|
||||
actionsPerTypeCounter.put(type, numActionsPerType-1);
|
||||
}
|
||||
numPendingCalls--;
|
||||
timepointOfLastSuccessfulJobExecution = MillisecondsTimePoint.now();
|
||||
timePointOfTypeLastBeingExecuted.put(type, MillisecondsTimePoint.now());
|
||||
checkForEmptyCallQueue(type);
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -22,37 +22,26 @@
|
||||
<module>com.sap.sse.gwt.adminconsole</module>
|
||||
<module>com.sap.sse.datamining</module>
|
||||
<module>com.sap.sse.datamining.shared</module>
|
||||
<module>com.sap.sse.datamining.test</module>
|
||||
<module>com.sap.sse.security</module>
|
||||
<module>com.sap.sse.security.replication.test</module>
|
||||
<module>com.sap.sse.security.test</module>
|
||||
<module>com.sap.sse.security.common</module>
|
||||
<module>com.sap.sse.security.ui</module>
|
||||
<module>com.sap.sse.security.userstore.mongodb</module>
|
||||
<module>com.sap.sse.operationaltransformation</module>
|
||||
<module>com.sap.sse.operationaltransformation.test</module>
|
||||
<module>com.sap.sse.replication</module>
|
||||
<module>com.sap.sse.replication.testsupport</module>
|
||||
<module>com.sap.sse.common.test</module>
|
||||
<module>com.sap.sse.filestorage</module>
|
||||
<module>com.sap.sse.filestorage.test</module>
|
||||
<module>com.sap.sailing.domain.common</module>
|
||||
<module>com.sap.sailing.domain.shared.android</module>
|
||||
<module>com.sap.sailing.domain</module>
|
||||
<module>com.sap.sailing.geocoding</module>
|
||||
<module>com.sap.sailing.datamining</module>
|
||||
<module>com.sap.sailing.datamining.shared</module>
|
||||
<module>com.sap.sailing.datamining.test</module>
|
||||
<module>com.sap.sailing.domain.persistence</module>
|
||||
<module>com.sap.sailing.domain.deckmanadapter</module>
|
||||
<module>com.sap.sailing.domain.deckmanadapter.test</module>
|
||||
<module>com.sap.sailing.domain.tractracadapter</module>
|
||||
<module>com.sap.sailing.domain.tractracadapter.persistence</module>
|
||||
<module>com.sap.sailing.domain.igtimiadapter</module>
|
||||
<module>com.sap.sailing.domain.igtimiadapter.persistence</module>
|
||||
<module>com.sap.sailing.domain.igtimiadapter.test</module>
|
||||
<module>com.sap.sailing.domain.racelogtrackingadapter</module>
|
||||
<module>com.sap.sailing.domain.racelogtrackingadapter.test</module>
|
||||
<module>com.sap.sailing.domain.racelogtrackingadapter.testsupport</module>
|
||||
<module>com.sap.sailing.domain.swisstimingadapter</module>
|
||||
<module>com.sap.sailing.domain.swisstimingadapter.persistence</module>
|
||||
@@ -68,7 +57,6 @@
|
||||
<module>com.sap.sailing.www</module>
|
||||
<module>com.sap.sailing.www.events</module>
|
||||
<module>com.sap.sailing.xmlexport</module>
|
||||
<module>com.sap.sailing.xmlexport.test</module>
|
||||
<module>com.google.gwt.osgi</module>
|
||||
<module>com.tractrac.clientmodule</module>
|
||||
<module>org.json.simple</module>
|
||||
@@ -82,18 +70,31 @@
|
||||
<module>com.sap.sailing.xrr.schema</module>
|
||||
<module>com.sap.sailing.xrr.resultimport</module>
|
||||
<module>com.sap.sailing.xrr.structureimport</module>
|
||||
<module>com.sap.sailing.xrr.resultimport.test</module>
|
||||
<module>com.sap.sailing.freg.resultimport</module>
|
||||
<module>org.openqa.selenium.osgi</module>
|
||||
<module>com.sap.sailing.monitoring</module>
|
||||
<module>com.sap.sailing.nmeaconnector</module>
|
||||
<module>net.sf.marineapi</module>
|
||||
<module>net.sf.marineapi.test</module>
|
||||
<module>com.sap.sailing.simulator</module>
|
||||
<module>com.sap.sailing.server.trackfiles</module>
|
||||
<module>com.sap.sailing.feature.runtime</module>
|
||||
<module>com.sap.sailing.gwt.ui</module>
|
||||
<module>com.sap.sailing.domain.test</module>
|
||||
<module>com.sap.sse.replication.testsupport</module>
|
||||
<module>com.sap.sse.gwt.test</module>
|
||||
<module>com.sap.sse.datamining.test</module>
|
||||
<module>com.sap.sse.security.replication.test</module>
|
||||
<module>com.sap.sse.security.test</module>
|
||||
<module>com.sap.sse.operationaltransformation.test</module>
|
||||
<module>com.sap.sse.common.test</module>
|
||||
<module>com.sap.sse.filestorage.test</module>
|
||||
<module>com.sap.sailing.datamining.test</module>
|
||||
<module>com.sap.sailing.domain.deckmanadapter.test</module>
|
||||
<module>com.sap.sailing.domain.igtimiadapter.test</module>
|
||||
<module>com.sap.sailing.domain.racelogtrackingadapter.test</module>
|
||||
<module>com.sap.sailing.xmlexport.test</module>
|
||||
<module>com.sap.sailing.xrr.resultimport.test</module>
|
||||
<module>net.sf.marineapi.test</module>
|
||||
<module>com.sap.sailing.domain.shared.android.test</module>
|
||||
<module>com.sap.sailing.geocoding.test</module>
|
||||
<module>com.sap.sailing.domain.swisstimingadapter.test</module>
|
||||
|
||||
Reference in New Issue
Block a user