TaskManager bug fixes and code cleanup

This commit is contained in:
Евгений Смирнов 2021-07-07 17:02:38 +03:00
parent 5a06788652
commit f520d4b2c6
4 changed files with 120 additions and 106 deletions

View File

@ -18,6 +18,7 @@
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
import org.apache.logging.log4j.LogManager;
import ru.windcorp.progressia.common.modules.Module; import ru.windcorp.progressia.common.modules.Module;
import ru.windcorp.progressia.common.modules.Task; import ru.windcorp.progressia.common.modules.Task;
import ru.windcorp.progressia.common.modules.TaskManager; import ru.windcorp.progressia.common.modules.TaskManager;
@ -29,10 +30,12 @@ public class AudioSystem {
AudioManager.initAL(); AudioManager.initAL();
Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook"); Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook");
Runtime.getRuntime().addShutdownHook(shutdownHook); Runtime.getRuntime().addShutdownHook(shutdownHook);
Task t = new Task("Task:InitializeAudio") {
Task t = new Task("AudioSystem:Initialize") {
@Override @Override
protected void perform() { protected void perform() {
loadAudioData(); loadAudioData();
LogManager.getLogger().info("Audio data is loaded");
} }
}; };
audioModule.addTask(t); audioModule.addTask(t);

View File

@ -1,12 +1,12 @@
package ru.windcorp.progressia.common.modules; package ru.windcorp.progressia.common.modules;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public class Module extends Namespaced { public class Module extends Namespaced {
private final List<Task> tasks = new ArrayList<>(); private final List<Task> tasks = new ArrayList<>();
@ -25,6 +25,7 @@ public class Module extends Namespaced {
public List<Task> getTasks() { public List<Task> getTasks() {
return tasks; return tasks;
} }
public void addTask(Task task) { public void addTask(Task task) {
tasks.add(task); tasks.add(task);
} }

View File

@ -7,13 +7,11 @@ import java.util.List;
public abstract class Task public abstract class Task
extends Namespaced extends Namespaced
implements Runnable implements Runnable {
{
private boolean isDone = false;
private boolean isActive = false;
List<Task> requiredTasks = new ArrayList<>(); List<Task> requiredTasks = new ArrayList<>();
private boolean isDone = false;
private boolean isActive = false;
protected Task(String id) { protected Task(String id) {
super(id); super(id);
@ -33,7 +31,9 @@ public abstract class Task
return isDone; return isDone;
} }
public boolean isActive() { return isActive; } public boolean isActive() {
return isActive;
}
public boolean canRun() { public boolean canRun() {
if (this.isActive) return false; if (this.isActive) return false;
@ -46,4 +46,8 @@ public abstract class Task
public List<Task> getRequiredTasks() { public List<Task> getRequiredTasks() {
return requiredTasks; return requiredTasks;
} }
public void addRequiredTask(Task task) {
requiredTasks.add(task);
}
} }

View File

@ -1,10 +1,14 @@
package ru.windcorp.progressia.common.modules; package ru.windcorp.progressia.common.modules;
import ru.windcorp.progressia.common.state.StateFieldBuilder;
import org.apache.logging.log4j.LogManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.Executors.newFixedThreadPool; import static java.util.concurrent.Executors.newFixedThreadPool;
@ -12,14 +16,13 @@ public class TaskManager {
private static final TaskManager instance = new TaskManager(); private static final TaskManager instance = new TaskManager();
private final List<Task> tasks = new ArrayList<>(); private final List<Task> tasks = new ArrayList<>();
private final List<Module> modules = new ArrayList<>(); private final List<Module> modules = new ArrayList<>();
private boolean loadingDone;
private int activeThreadsCount;
private final ExecutorService executorService; private final ExecutorService executorService;
private final AtomicBoolean loadingDone;
private final AtomicInteger activeThreadsCount;
private TaskManager() { private TaskManager() {
loadingDone = false; loadingDone = new AtomicBoolean(false);
activeThreadsCount = 0; activeThreadsCount = new AtomicInteger(0);
executorService = newFixedThreadPool( executorService = newFixedThreadPool(
Runtime.getRuntime().availableProcessors(), Thread::new); Runtime.getRuntime().availableProcessors(), Thread::new);
} }
@ -34,25 +37,23 @@ public class TaskManager {
} }
public boolean isLoadingDone() { public boolean isLoadingDone() {
return loadingDone; return loadingDone.get();
} }
public void startLoading() { public void startLoading() {
LogManager.getLogger().info("Loading is started");
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
executorService.submit(() -> { executorService.submit(() -> {
while(!loadingDone) { while (!loadingDone.get()) {
Task t = getRunnableTask(); Task t = getRunnableTask();
if (t != null) { if (t != null) {
synchronized (this) { activeThreadsCount.incrementAndGet();
activeThreadsCount++;
}
t.run(); t.run();
activeThreadsCount.decrementAndGet();
synchronized (this) { synchronized (this) {
activeThreadsCount--;
notifyAll(); notifyAll();
} }
} else if (activeThreadsCount > 0) { } else if (activeThreadsCount.get() > 0) {
try { try {
synchronized (this) { synchronized (this) {
this.wait(); this.wait();
@ -61,8 +62,9 @@ public class TaskManager {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
loadingDone.set(true);
synchronized (this) { synchronized (this) {
loadingDone = true; notifyAll();
} }
} }
} }
@ -70,6 +72,10 @@ public class TaskManager {
} }
waitForLoadingEnd(); waitForLoadingEnd();
if (!tasks.isEmpty()) {
throw CrashReports.crash(new Exception("Loading is failed"), "");
}
LogManager.getLogger().info("Loading is finished");
executorService.shutdownNow(); executorService.shutdownNow();
} }
@ -88,7 +94,7 @@ public class TaskManager {
private void waitForLoadingEnd() { private void waitForLoadingEnd() {
synchronized (this) { synchronized (this) {
while(!loadingDone) { while (!loadingDone.get()) {
try { try {
this.wait(); this.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {