Skip to content

Adding features for testing reliability #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/vcs.xml
.idea/various.iml
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.infiniteautomation</groupId>
<artifactId>various</artifactId>
<version>1.0.1-SNAPSHOT</version>
<name>Sero Various Libraries</name>
<description></description>
<url>https://github.com/infiniteautomation/various</url>
<licenses>
<license>
<name>MPL 2.0</name>
<url> https://www.mozilla.org/en-US/MPL/2.0/.</url>
</license>
</licenses>
<organization>
<name>Radix IoT</name>
<url>https://www.radixiot.com/</url>
</organization>
</project>
56 changes: 56 additions & 0 deletions sero-warp/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lohbihler</groupId>
<artifactId>sero-warp</artifactId>
<version>1.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<licenses>
<license>
<name>MPL 2.0</name>
<url>https://www.mozilla.org/en-US/MPL/2.0/.</url>
</license>
</licenses>
<organization>
<name>Radix IoT</name>
<url>https://www.radixiot.com/</url>
</organization>
<dependencies>
<dependency>
<groupId>lohbihler</groupId>
<artifactId>sero-scheduler</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>ias-snapshots</id>
<url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>
</repository>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>ias-releases</id>
<url>https://maven.mangoautomation.net/repository/ias-release/</url>
</repository>
</repositories>
</project>
83 changes: 83 additions & 0 deletions sero-warp/src/main/java/lohbihler/warp/OrderedExecutorService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package lohbihler.warp;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* @author Terry Packer
*/
public class OrderedExecutorService extends ThreadPoolExecutor {

/**
* Lock held on access to workers set and related bookkeeping. While we could use a concurrent
* set of some sort, it turns out to be generally preferable to use a lock. Among the reasons is
* that this serializes interruptIdleWorkers, which avoids unnecessary interrupt storms,
* especially during shutdown. Otherwise exiting threads would concurrently interrupt those that
* have not yet interrupted. It also simplifies some of the associated statistics bookkeeping of
* largestPoolSize etc. We also hold mainLock on shutdown and shutdownNow, for the sake of
* ensuring workers set is stable while separately checking permission to interrupt and actually
* interrupting.
*/
private final ReentrantReadWriteLock mainLock = new ReentrantReadWriteLock();

private OrderedRunnable first;

public OrderedExecutorService(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

@Override
public void execute(Runnable command) {
ReentrantReadWriteLock lock = mainLock;
lock.writeLock().lock();
try {
if (first == null) {
first = new OrderedRunnable(null, command);
} else {
first = new OrderedRunnable(first, command);
}
} finally {
lock.writeLock().unlock();
}
super.execute(first);
}

private class OrderedRunnable implements Runnable {

private final OrderedRunnable previous;
private volatile CountDownLatch latch;
private final Runnable command;
private volatile boolean success = false;
private volatile boolean done = false;

public OrderedRunnable(OrderedRunnable previous, Runnable command) {
this.previous = previous;
this.command = command;
this.latch = new CountDownLatch(1);
}

public void await() throws InterruptedException {
latch.await();
}

@Override
public void run() {
try {
command.run();
success = true;
if (previous != null) {
previous.await();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
done = true;
latch.countDown();
}
}
}
}
Loading