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;
|
||||
|
||||
/**
|
||||
* 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;)
|
||||
*/
|
||||
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 period time to wait between runs
|
||||
* @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;
|
||||
}
|
||||
|
@ -1,15 +1,29 @@
|
||||
package fr.altarik.toolbox.task.syncTasks;
|
||||
|
||||
import fr.altarik.toolbox.task.AltarikRunnable;
|
||||
package fr.altarik.toolbox.task;
|
||||
|
||||
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;
|
||||
/**
|
||||
* 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 AltarikRunnable function;
|
||||
|
||||
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) {
|
||||
this.function = function;
|
||||
this.delay = delay;
|
||||
@ -36,4 +50,6 @@ public class SchedulerTaskData {
|
||||
public long getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package fr.altarik.toolbox.task;
|
||||
|
||||
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks;
|
||||
import fr.altarik.toolbox.task.async.AsyncTasks;
|
||||
import net.fabricmc.api.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 java.util.ArrayList;
|
||||
@ -56,7 +58,7 @@ public class AsyncPeriodicTasks implements PeriodicTaskI, AsyncTaskI {
|
||||
|
||||
@Override
|
||||
public void addTask(AltarikRunnable function) throws InterruptedException {
|
||||
this.addTask(function, 0, 1);
|
||||
this.addTask(function, 0, 1000);
|
||||
}
|
||||
|
||||
@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.TaskI;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
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.
|
||||
*/
|
||||
public class AsyncTasks implements TaskI {
|
||||
public class AsyncTasks implements AsyncTaskI {
|
||||
|
||||
private final ExecutorService worker;
|
||||
|
||||
@ -30,11 +29,11 @@ public class AsyncTasks implements TaskI {
|
||||
*
|
||||
* @return an instance of AsyncTasks
|
||||
*/
|
||||
public static TaskI initialize(int numberOfWorker) {
|
||||
public static AsyncTaskI initialize(int numberOfWorker) {
|
||||
return new AsyncTasks(numberOfWorker);
|
||||
}
|
||||
|
||||
public static TaskI initialize() {
|
||||
public static AsyncTaskI initialize() {
|
||||
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;
|
||||
|
||||
public class TaskScheduler {
|
||||
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;
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@ -30,12 +41,13 @@ public class TaskScheduler {
|
||||
asyncTasks.remove(data);
|
||||
if(!data.getFunction().isCancelled()) {
|
||||
long currentDelay = data.getCurrentDelay();
|
||||
if(currentDelay != 0) {
|
||||
data.setCurrentDelay(currentDelay - 1);
|
||||
asyncTasks.addElement(data);
|
||||
} else {
|
||||
Instant currentTime = Instant.now();
|
||||
Instant lastExecution = lastTimeExecution.get(data);
|
||||
// (lastExec + delay) - currentTime
|
||||
if(lastExecution.plus(currentDelay, ChronoUnit.MILLIS).isBefore(currentTime)) {
|
||||
data.getFunction().run();
|
||||
data.setCurrentDelay(data.getPeriod());
|
||||
lastTimeExecution.put(data, Instant.now());
|
||||
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.minecraft.server.MinecraftServer;
|
||||
@ -13,7 +13,7 @@ public class ServerTickListener {
|
||||
}
|
||||
|
||||
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.TaskI;
|
||||
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks;
|
||||
import fr.altarik.toolbox.task.async.AsyncTaskI;
|
||||
import fr.altarik.toolbox.task.async.AsyncTasks;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Date;
|
||||
@ -21,7 +20,7 @@ class AsyncTaskTest {
|
||||
void testAsyncOp() throws Exception {
|
||||
int numberOfTasks = 10000;
|
||||
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<>();
|
||||
for(int i = 0; i < numberOfTasks; i++) {
|
||||
System.out.println(log("sending task " + i));
|
||||
@ -40,6 +39,5 @@ class AsyncTaskTest {
|
||||
expected[i] = i;
|
||||
}
|
||||
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