Compare commits
2 Commits
b1ee9344b8
...
e9c97df089
Author | SHA1 | Date | |
---|---|---|---|
e9c97df089 | |||
e7178d44a9 |
@ -5,7 +5,7 @@ public abstract class AltarikRunnable implements Runnable {
|
|||||||
private boolean isCancelled = false;
|
private boolean isCancelled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning: Some task cannot be cancelled (mostly async tasks like {@link fr.altarik.toolbox.task.asyncTasks.AsyncTasks}
|
* Warning: Some task cannot be cancelled (mostly async tasks like {@link fr.altarik.toolbox.task.async.AsyncTasks}
|
||||||
* The result of this call is ignored in this case, you can still add a way to not execute its content (like if(isCancelled) return;)
|
* The result of this call is ignored in this case, you can still add a way to not execute its content (like if(isCancelled) return;)
|
||||||
*/
|
*/
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
package fr.altarik.toolbox.task;
|
|
||||||
|
|
||||||
public interface AsyncTaskI extends TaskI, AutoCloseable {
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ public interface PeriodicTaskI extends TaskI {
|
|||||||
* @param delay delay before starting the task
|
* @param delay delay before starting the task
|
||||||
* @param period time to wait between runs
|
* @param period time to wait between runs
|
||||||
* @throws InterruptedException When executed asynchronously, task may be interrupted
|
* @throws InterruptedException When executed asynchronously, task may be interrupted
|
||||||
* @see fr.altarik.toolbox.task.syncTasks.PeriodicSyncTask
|
* @see fr.altarik.toolbox.task.sync.PeriodicSyncTask
|
||||||
*/
|
*/
|
||||||
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException;
|
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,29 @@
|
|||||||
package fr.altarik.toolbox.task.syncTasks;
|
package fr.altarik.toolbox.task;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.AltarikRunnable;
|
|
||||||
|
|
||||||
public class SchedulerTaskData {
|
public class SchedulerTaskData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay before executing the function for the first time
|
||||||
|
* Correspond to tick in synchronous context and milliseconds in asynchronous context
|
||||||
|
*/
|
||||||
private final long delay;
|
private final long delay;
|
||||||
|
/**
|
||||||
|
* Period of time before re-executing the function
|
||||||
|
* Correspond to tick in synchronous context and milliseconds in asynchronous context
|
||||||
|
*/
|
||||||
private final long period;
|
private final long period;
|
||||||
private final AltarikRunnable function;
|
private final AltarikRunnable function;
|
||||||
|
|
||||||
private long currentDelay;
|
private long currentDelay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Delay and Period times corresponds to tick in synchronous context and milliseconds in asynchronous context
|
||||||
|
*
|
||||||
|
* @param function instructions to execute
|
||||||
|
* @param delay Delay before executing the function for the first time
|
||||||
|
* @param period Period of time before re-executing the function
|
||||||
|
*/
|
||||||
public SchedulerTaskData(AltarikRunnable function, long delay, long period) {
|
public SchedulerTaskData(AltarikRunnable function, long delay, long period) {
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.delay = delay;
|
this.delay = delay;
|
||||||
@ -36,4 +50,6 @@ public class SchedulerTaskData {
|
|||||||
public long getPeriod() {
|
public long getPeriod() {
|
||||||
return period;
|
return period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package fr.altarik.toolbox.task;
|
package fr.altarik.toolbox.task;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks;
|
import fr.altarik.toolbox.task.async.AsyncTasks;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
|
||||||
public class Task implements ModInitializer {
|
public class Task implements ModInitializer {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package fr.altarik.toolbox.task.asyncTasks;
|
package fr.altarik.toolbox.task.async;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.*;
|
import fr.altarik.toolbox.task.AltarikRunnable;
|
||||||
|
import fr.altarik.toolbox.task.PeriodicTaskI;
|
||||||
|
import fr.altarik.toolbox.task.TaskI;
|
||||||
import it.unimi.dsi.fastutil.ints.IntComparators;
|
import it.unimi.dsi.fastutil.ints.IntComparators;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -56,7 +58,7 @@ public class AsyncPeriodicTasks implements PeriodicTaskI, AsyncTaskI {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addTask(AltarikRunnable function) throws InterruptedException {
|
public void addTask(AltarikRunnable function) throws InterruptedException {
|
||||||
this.addTask(function, 0, 1);
|
this.addTask(function, 0, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -0,0 +1,6 @@
|
|||||||
|
package fr.altarik.toolbox.task.async;
|
||||||
|
|
||||||
|
import fr.altarik.toolbox.task.TaskI;
|
||||||
|
|
||||||
|
public interface AsyncTaskI extends TaskI, AutoCloseable {
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package fr.altarik.toolbox.task.asyncTasks;
|
package fr.altarik.toolbox.task.async;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.AltarikRunnable;
|
import fr.altarik.toolbox.task.AltarikRunnable;
|
||||||
import fr.altarik.toolbox.task.TaskI;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -10,7 +9,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
/**
|
/**
|
||||||
* A non-blocking small sized time-consuming tasks to executed asynchronously.
|
* A non-blocking small sized time-consuming tasks to executed asynchronously.
|
||||||
*/
|
*/
|
||||||
public class AsyncTasks implements TaskI {
|
public class AsyncTasks implements AsyncTaskI {
|
||||||
|
|
||||||
private final ExecutorService worker;
|
private final ExecutorService worker;
|
||||||
|
|
||||||
@ -30,11 +29,11 @@ public class AsyncTasks implements TaskI {
|
|||||||
*
|
*
|
||||||
* @return an instance of AsyncTasks
|
* @return an instance of AsyncTasks
|
||||||
*/
|
*/
|
||||||
public static TaskI initialize(int numberOfWorker) {
|
public static AsyncTaskI initialize(int numberOfWorker) {
|
||||||
return new AsyncTasks(numberOfWorker);
|
return new AsyncTasks(numberOfWorker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TaskI initialize() {
|
public static AsyncTaskI initialize() {
|
||||||
return initialize(Runtime.getRuntime().availableProcessors());
|
return initialize(Runtime.getRuntime().availableProcessors());
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +1,27 @@
|
|||||||
package fr.altarik.toolbox.task;
|
package fr.altarik.toolbox.task.async;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.syncTasks.SchedulerTaskData;
|
import fr.altarik.toolbox.task.AltarikRunnable;
|
||||||
|
import fr.altarik.toolbox.task.SchedulerTaskData;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
public class TaskScheduler {
|
public class TaskScheduler {
|
||||||
private Vector<SchedulerTaskData> asyncTasks;
|
private Vector<SchedulerTaskData> asyncTasks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return last time the method was executed, Value initialized to now when using sending the task to scheduler
|
||||||
|
*/
|
||||||
|
private HashMap<SchedulerTaskData, Instant> lastTimeExecution;
|
||||||
private boolean stop = false;
|
private boolean stop = false;
|
||||||
|
|
||||||
|
|
||||||
public synchronized void sendAsyncTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
|
public synchronized void sendAsyncTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
|
||||||
asyncTasks.addElement(new SchedulerTaskData(function, delay, period));
|
SchedulerTaskData data = new SchedulerTaskData(function, delay, period);
|
||||||
|
asyncTasks.addElement(data);
|
||||||
|
lastTimeExecution.put(new SchedulerTaskData(function, delay, period), Instant.now());
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,12 +41,13 @@ public class TaskScheduler {
|
|||||||
asyncTasks.remove(data);
|
asyncTasks.remove(data);
|
||||||
if(!data.getFunction().isCancelled()) {
|
if(!data.getFunction().isCancelled()) {
|
||||||
long currentDelay = data.getCurrentDelay();
|
long currentDelay = data.getCurrentDelay();
|
||||||
if(currentDelay != 0) {
|
Instant currentTime = Instant.now();
|
||||||
data.setCurrentDelay(currentDelay - 1);
|
Instant lastExecution = lastTimeExecution.get(data);
|
||||||
asyncTasks.addElement(data);
|
// (lastExec + delay) - currentTime
|
||||||
} else {
|
if(lastExecution.plus(currentDelay, ChronoUnit.MILLIS).isBefore(currentTime)) {
|
||||||
data.getFunction().run();
|
data.getFunction().run();
|
||||||
data.setCurrentDelay(data.getPeriod());
|
data.setCurrentDelay(data.getPeriod());
|
||||||
|
lastTimeExecution.put(data, Instant.now());
|
||||||
asyncTasks.addElement(data);
|
asyncTasks.addElement(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package fr.altarik.toolbox.task.sync;
|
||||||
|
|
||||||
|
import fr.altarik.toolbox.task.AltarikRunnable;
|
||||||
|
import fr.altarik.toolbox.task.PeriodicTaskI;
|
||||||
|
import fr.altarik.toolbox.task.SchedulerTaskData;
|
||||||
|
import fr.altarik.toolbox.task.TaskI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PeriodicSyncTask implements PeriodicTaskI, Runnable {
|
||||||
|
|
||||||
|
private ServerTickListener listener;
|
||||||
|
private List<SchedulerTaskData> tasks;
|
||||||
|
|
||||||
|
private PeriodicSyncTask() {
|
||||||
|
this.listener = new ServerTickListener(this);
|
||||||
|
this.tasks = new ArrayList<>(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static TaskI initialize() {
|
||||||
|
return new PeriodicSyncTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTask(AltarikRunnable function) throws InterruptedException {
|
||||||
|
addTask(function, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<SchedulerTaskData> removeList = new ArrayList<>(tasks.size());
|
||||||
|
for(SchedulerTaskData data : tasks) {
|
||||||
|
if(!data.getFunction().isCancelled()) {
|
||||||
|
long currentDelay = data.getCurrentDelay();
|
||||||
|
if(currentDelay != 0) {
|
||||||
|
data.setCurrentDelay(currentDelay - 1);
|
||||||
|
} else {
|
||||||
|
data.getFunction().run();
|
||||||
|
data.setCurrentDelay(data.getPeriod());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removeList.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(SchedulerTaskData toRemove : removeList) {
|
||||||
|
tasks.remove(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
|
||||||
|
tasks.add(new SchedulerTaskData(function, delay, period));
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package fr.altarik.toolbox.task.syncTasks;
|
package fr.altarik.toolbox.task.sync;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
@ -13,7 +13,7 @@ public class ServerTickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onServerTick(MinecraftServer minecraftServer) {
|
private void onServerTick(MinecraftServer minecraftServer) {
|
||||||
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,48 +0,0 @@
|
|||||||
package fr.altarik.toolbox.task.syncTasks;
|
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.AltarikRunnable;
|
|
||||||
import fr.altarik.toolbox.task.PeriodicTaskI;
|
|
||||||
import fr.altarik.toolbox.task.TaskI;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PeriodicSyncTask implements PeriodicTaskI, Runnable {
|
|
||||||
|
|
||||||
private ServerTickListener listener;
|
|
||||||
private List<AltarikRunnable> tasks;
|
|
||||||
|
|
||||||
private PeriodicSyncTask() {
|
|
||||||
this.listener = new ServerTickListener(this);
|
|
||||||
this.tasks = new ArrayList<>(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static TaskI initialize() {
|
|
||||||
return new PeriodicSyncTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTask(AltarikRunnable function) throws InterruptedException {
|
|
||||||
tasks.add(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
List<AltarikRunnable> removeList = new ArrayList<>(tasks.size());
|
|
||||||
for(AltarikRunnable task : tasks) {
|
|
||||||
if(task.isCancelled()) {
|
|
||||||
removeList.add(task);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
task.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks.removeAll(removeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,7 @@
|
|||||||
package fr.altarik.toolbox;
|
package fr.altarik.toolbox.task;
|
||||||
|
|
||||||
import fr.altarik.toolbox.task.AltarikRunnable;
|
import fr.altarik.toolbox.task.async.AsyncTaskI;
|
||||||
import fr.altarik.toolbox.task.TaskI;
|
import fr.altarik.toolbox.task.async.AsyncTasks;
|
||||||
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -21,7 +20,7 @@ class AsyncTaskTest {
|
|||||||
void testAsyncOp() throws Exception {
|
void testAsyncOp() throws Exception {
|
||||||
int numberOfTasks = 10000;
|
int numberOfTasks = 10000;
|
||||||
System.out.println("Initializing async tasks worker");
|
System.out.println("Initializing async tasks worker");
|
||||||
TaskI worker = AsyncTasks.initialize(1); // only testing on a single worker, otherwise result have a high chance to not be in the order we want
|
AsyncTaskI worker = AsyncTasks.initialize(1); // only testing on a single worker, otherwise result have a high chance to not be in the order we want
|
||||||
Stack<Integer> results = new Stack<>();
|
Stack<Integer> results = new Stack<>();
|
||||||
for(int i = 0; i < numberOfTasks; i++) {
|
for(int i = 0; i < numberOfTasks; i++) {
|
||||||
System.out.println(log("sending task " + i));
|
System.out.println(log("sending task " + i));
|
||||||
@ -40,6 +39,5 @@ class AsyncTaskTest {
|
|||||||
expected[i] = i;
|
expected[i] = i;
|
||||||
}
|
}
|
||||||
assertArrayEquals(expected, results.toArray());
|
assertArrayEquals(expected, results.toArray());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package fr.altarik.toolbox.task;
|
||||||
|
|
||||||
|
public class SyncTaskTest {
|
||||||
|
|
||||||
|
// TODO: 03/02/2023 Envoyé les tasks au workers grâce à un autre thread.
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user