Compare commits

...

17 Commits

Author SHA1 Message Date
Paldiu
25ea207677
Update README.md 2023-04-14 00:26:53 -05:00
Paldiu
a4f1e01c87 Merge branch 'main' of https://github.com/SimplexDevelopment/SimplexSS 2022-12-21 15:31:55 -06:00
Paldiu
ec92490ffd Update ServiceManager.java 2022-12-21 15:31:42 -06:00
Paldiu
cccd441432
Update README.md 2022-12-15 13:37:50 -06:00
Paldiu
0d91f86054
Update badge 2022-12-15 13:36:35 -06:00
Paldiu
116fbe5847 Merge branch 'main' of https://github.com/SimplexDevelopment/SimplexSS 2022-12-15 13:32:33 -06:00
Paldiu
c9fa0c1ca0 Switch to using Mono.create()
Switched from using Mono.just(T) and Mono.empty() for creating Mono<Void> objects to Mono.create(sink -> {});
2022-12-15 13:32:28 -06:00
Paldiu
695b1f9549
Update README.md 2022-12-15 08:22:07 -06:00
Paldiu
9d726cc1e3
Update README.md 2022-12-15 00:25:42 -06:00
Paldiu
5d66ea6582
Update README.md 2022-12-15 00:13:09 -06:00
Paldiu
7e29987e7f
Update README.md 2022-12-15 00:09:37 -06:00
Paldiu
5b2961fff1
Update README.md 2022-12-14 23:48:44 -06:00
Paldiu
8f6b327d20
Update README.md 2022-12-14 23:48:27 -06:00
Paldiu
42aef3b955
Update README.md 2022-12-14 23:46:55 -06:00
Paldiu
6c0229e910
Update README.md 2022-12-14 23:46:34 -06:00
Paldiu
0805d44dc5
Create codeql.yml 2022-12-14 23:41:50 -06:00
Paldiu
8442753964
Create gradle.yml 2022-12-14 23:40:50 -06:00
8 changed files with 297 additions and 26 deletions

76
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '21 13 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

34
.github/workflows/gradle.yml vendored Normal file
View File

@ -0,0 +1,34 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build

133
README.md
View File

@ -1,2 +1,135 @@
[here]: https://simplexdevelopment.github.io/SimplexSS "SimplexSS JavaDocs"
# SimplexSS
![](https://img.shields.io/github/license/SimplexDevelopment/SimplexSS)
![](https://img.shields.io/github/languages/top/SimplexDevelopment/SimplexSS)
![](https://img.shields.io/github/actions/workflow/status/SimplexDevelopment/SimplexSS/codeql.yml?branch=main)
![](https://img.shields.io/github/v/release/SimplexDevelopment/SimplexSS?include_prereleases)
![](https://jitpack.io/v/SimplexDevelopment/SimplexSS.svg)
![](https://img.shields.io/github/issues/SimplexDevelopment/SimplexSS)
![](https://img.shields.io/github/stars/SimplexDevelopment/SimplexSS?style=social)
![](https://img.shields.io/github/forks/SimplexDevelopment/SimplexSS?style=social)
A reactive non blocking api for scheduling runnable tasks (called services)
JavaDocs can be found [here].
# Adding SimplexSS to your project
In order to use SimplexSS in your project, you need to add the jitpack repository to your build.gradle or pom.xml file.
Here's an example, in Gradle:
```gradle
repositories {
maven {
id 'jitpack'
url 'https://jitpack.io'
}
}
```
Then, you can add the dependency.
The `groupId` is `com.github.SimplexDevelopment`
The `artifactId` is `SimplexSS`
The `version` is `1.0.1-SNAPSHOT`
It is recommended you use either the Maven Shade Plugin,
```maven
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>path.to.MainClass</mainClass>
</manifest>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
```
or the Gradle Shadow Plugin (com.github.johnrengelman.shadow).
```gradle
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
```
Here is an example of the dependency, in Gradle:
```gradle
dependencies {
shadow 'com.github.SimplexDevelopment:SimplexSS:1.0.1-SNAPSHOT'
}
```
# Using SimplexSS
To use Simplex Scheduling System, the first thing you need to do is initialize a new instance of the Scheduling System.
```Java
private SchedulingSystem<YourPlugin> scheduler;
@Override
public void onEnable() {
this.scheduler = new SchedulingSystem<>(this);
}
```
Then, you should use the Service Manager to create some new service pools. You can use `ServicePool#emptyBukkitServicePool(String, JavaPlugin)` for a service pool which will operate on the main server thread, or you can use `ServicePool#emptyServicePool(String, boolean)` for a completely separate, non-blocking scheduler which can be either singular or multithreaded. You should also use the service manager stream to register your services, and assign a Flux<Disposable> object so we can cancel the services later on in `JavaPlugin#onDisable()`.
```Java
private SchedulingSystem<YourPlugin> scheduler;
private Flux<Disposable> disposables;
@Override
public void onEnable() {
this.scheduler = new SchedulingSystem<>(this);
YourFirstService firstService;
YourSecondService secondService;
YourThirdService thirdService;
scheduler.getServiceManager().subscribe(manager -> {
manager.emptyBukkitServicePool("pool_name", this).subscribe(pool -> {
Set<Disposable> dispos = new HashSet<>();
firstService = new YourFirstService(pool, "first_service_name");
secondService = new YourSecondService(pool, "second_service_name", 20 * 60L);
thirdService = new YourThirdService(pool, "third_service_name", 20 * 60L, 20 * 60 * 10L, true, false);
scheduler.queue(firstService).subscribe(dispos::add);
scheduler.queue(secondService).subscribe(dispos::add);
scheduler.queue(thirdService).subscribe(dispos::add);
disposables = Flux.fromIterable(dispos);
});
});
}
```
You can then stop, cancel, and/or dispose of the tasks in your `JavaPlugin#onDisable()` method by calling:
```Java
@Override
public void onDisable() {
scheduler.getServiceManager().subscribe(manager -> {
manager.getServicePools().doOnEach(signal -> Objects.requireNonNull(signal.get())
.stopServices(disposables)
.subscribe());
});
}
```

View File

@ -26,7 +26,6 @@ package io.github.simplexdevelopment.impl;
import io.github.simplexdevelopment.scheduler.ExecutableService;
import io.github.simplexdevelopment.scheduler.ServicePool;
import org.bukkit.plugin.java.JavaPlugin;
import reactor.core.publisher.Mono;
public class ServiceImpl extends ExecutableService {
@ -39,18 +38,18 @@ public class ServiceImpl extends ExecutableService {
@Override
public Mono<Void> start() {
return Mono.just(plugin)
.map(JavaPlugin::getLogger)
.doOnNext(l -> l.info("The service has executed successfully!"))
.then();
return Mono.create(sink -> {
plugin.getLogger().info("The service has started successfully!");
sink.success();
});
}
@Override
public Mono<Void> stop() {
return Mono.just(plugin)
.map(JavaPlugin::getLogger)
.doOnNext(l -> l.info("The service has stopped"))
.then();
return Mono.create(sink -> {
plugin.getLogger().info("The service has stopped successfully!");
sink.success();
});
}
@Override

View File

@ -181,7 +181,15 @@ public abstract class ExecutableService implements IService {
this.delay = Objects.requireNonNullElse(delay, 0L);
this.period = Objects.requireNonNullElse(period, (20L * 60L) * 20L);
this.mayInterruptWhenRunning = mayInterruptWhenRunning;
this.parentPool = parentPool;
if (parentPool == null) {
this.parentPool = new ServicePool("defaultPool" + SchedulingSystem.denom, false);
SchedulingSystem.denom++;
} else {
this.parentPool = parentPool;
}
this.parentPool.getAssociatedServices().add(this);
}
@Override
@ -245,6 +253,9 @@ public abstract class ExecutableService implements IService {
@Override
public Mono<Void> setParentPool(ServicePool servicePool) {
return Mono.just(servicePool).doOnNext(pool -> this.parentPool = pool).then();
return Mono.create(sink -> {
this.parentPool = servicePool;
sink.success();
});
}
}

View File

@ -102,11 +102,7 @@ public final class SchedulingSystem<T extends JavaPlugin> implements ISchedule {
@Override
public @NotNull Mono<Void> runOnce(IService service) {
return Mono.just(service)
.doOnNext(s -> s.start()
.then(s.stop())
.subscribe())
.then();
return Mono.create(sink -> service.start().then(service.stop()).subscribe(sink::success));
}
@Override

View File

@ -33,6 +33,7 @@ import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@ -132,16 +133,35 @@ public final class ServiceManager {
}
/**
* Adds a service to an existing service pool.
*
* @param pool The service pool to add to.
* @param services The services to register within the service pool.
* @return A {@link Mono} object which contains the {@link ServicePool} element that now contains the registered services.
*/
@Contract("_, _ -> new")
public @NotNull Mono<ServicePool> addToExistingPool(@NotNull ServicePool pool, IService... services) {
Flux.fromIterable(Arrays.asList(services)).doOnEach(s -> {
pool.addService(s.get());
public @NotNull Mono<ServicePool> addToExistingPool(@NotNull String poolName, IService... services) {
return Mono.create(sink -> {
final ServicePool[] servicePool = new ServicePool[1];
findPool(poolName).subscribe(pool -> {
if (pool == null) throw new ServicePoolException("There is no pool currently registered with that name.");
servicePool[0] = pool;
});
List<IService> serviceList = Arrays.asList(services);
Flux.fromIterable(serviceList).doOnEach(s -> servicePool[0].addService(s.get()));
sink.success(servicePool[0]);
});
return Mono.just(pool);
}
/**
* Finds a {@link ServicePool} within the ServiceManager's pool list.
*
* @param poolName The name of the pool.
* @return A Mono object which holds the requested ServicePool, or an empty Mono if the pool does not exist.
*/
@Contract()
public @NotNull Mono<ServicePool> findPool(String poolName) {
return getServicePools().filter(pool -> pool.getName().equalsIgnoreCase(poolName)).next();
}
/**

View File

@ -186,11 +186,13 @@ public final class ServicePool implements Identifier {
* @return A {@link Mono<Void>} object which can be used to stop the service.
*/
public @NotNull Mono<Void> stopService(@NotNull String service_name, @Nullable Mono<Disposable> disposable) {
getService(service_name).doOnNext(IService::stop).subscribe();
if (disposable != null) {
disposable.doOnNext(Disposable::dispose).subscribe();
}
return Mono.empty();
return Mono.create(sink -> {
getService(service_name).doOnNext(IService::stop).subscribe();
if (disposable != null) {
disposable.doOnNext(Disposable::dispose).subscribe();
}
sink.success();
});
}
/**
@ -223,7 +225,7 @@ public final class ServicePool implements Identifier {
*/
public @NotNull Mono<ServicePool> recycle() {
this.getAssociatedServices().clear();
return Mono.just(this);
return Mono.create(sink -> sink.success(this));
}
/**