Documentation for module system and minor changes.

This commit is contained in:
Евгений Смирнов 2021-07-10 21:46:15 +03:00
parent 953614a7d8
commit 3b24ee0531
3 changed files with 94 additions and 17 deletions

View File

@ -23,24 +23,36 @@ import java.util.*;
public class Module extends Namespaced {
private final List<Task> tasks = new ArrayList<>();
private final Set<Task> tasks = new HashSet<>();
private final Map<String, String> meta = new HashMap<>();
private final Map<String, String> unmodifiableMeta = Collections.unmodifiableMap(meta);
private final Set<Task> unmodifiableTasks = Collections.unmodifiableSet(tasks);
/**
* @param id the identifier of a task object.
* Its format is restricted by {@link Namespaced}.
* @see Namespaced#Namespaced
*/
public Module(String id) {
super(id);
meta.put("id", id);
}
/**
* @return meta information of the module as {@link Map}.
*/
public Map<String, String> getMeta() {
return unmodifiableMeta;
}
public List<Task> getTasks() {
return tasks;
public Set<Task> getTasks() {
return unmodifiableTasks;
}
/**
* @param task that will be attached to the module.
* A task can't be added to any module second time.
*/
public void addTask(Task task) {
task.setOwner(this);
tasks.add(task);

View File

@ -22,21 +22,34 @@ import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class Task
extends Namespaced
implements Runnable {
List<Task> requiredTasks = new ArrayList<>();
private boolean isDone = false;
private boolean isActive = false;
private final Set<Task> requiredTasks = new HashSet<>();
private final AtomicBoolean isDone = new AtomicBoolean(false);
private final AtomicBoolean isActive = new AtomicBoolean(false);
private Module owner;
/**
* @param id the identifier of a task object.
* Its format is restricted by {@link Namespaced}.
* @see Namespaced#Namespaced
*/
public Task(String id) {
super(id);
}
/**
* @param id the identifier of a task object.
* Its format is restricted by {@link Namespaced}.
* @param module to which the task will be attached.
* @see Namespaced#Namespaced
*/
public Task(String id, Module module) {
this(id);
module.addTask(this);
@ -59,32 +72,44 @@ public abstract class Task
throw CrashReports.report(new Throwable(),
"The task cannot be performed second time");
} else {
isActive = true;
isActive.set(true);
perform();
isDone = true;
isActive.set(false);
isDone.set(true);
}
}
//This method will be invoked by Run()
/**
* The method is to be invoked in run().
* @see Task#run()
*/
protected abstract void perform();
public boolean isDone() {
return isDone;
return isDone.get();
}
/**
* @return if the {@link Task#run()} method is being invoked at the moment or not.
*/
public boolean isActive() {
return isActive;
return isActive.get();
}
/**
*
* @return true - the method is not done and not active
* and all requirement tasks are done, false - otherwise.
*/
public boolean canRun() {
if (this.isActive) return false;
if (this.isActive.get() || isDone.get()) return false;
for (Task reqT : requiredTasks) {
if (!reqT.isDone()) return false;
}
return true;
}
public List<Task> getRequiredTasks() {
public Set<Task> getRequiredTasks() {
return requiredTasks;
}
@ -92,14 +117,21 @@ public abstract class Task
requiredTasks.add(task);
}
/**
* @return the module the task is attached to.
*/
public Module getOwner() {
return owner;
}
/**
* @param module to which the task will be attached.
* Only one module can be the owner of the task.
*/
public void setOwner(Module module) {
if (owner != null) {
CrashReports.crash(
new Exception("Owner is not null")
new Throwable()
, "Could not set %s as owner of %s, because %s is already owner of it.",
module.getId(), this.getId(), this.getOwner().getId());
} else {

View File

@ -53,15 +53,34 @@ public class TaskManager {
return instance;
}
/**
* Registers the module and its tasks that are
* to be performed by {@link TaskManager#startLoading()}.
*
* @param module from where to register tasks for loading.
*/
public void registerModule(Module module) {
tasks.addAll(module.getTasks());
modules.add(module);
}
/**
* Registers a task that is to be performed
* by {@link TaskManager#startLoading()}.
*
* @param task to register for loading.
*/
public void addTask(Task task) {
tasks.add(task);
}
public boolean isLoadingDone() {
return loadingDone.get();
}
/**
* The method to start loading. It will perform every registered task.
*/
public void startLoading() {
LogManager.getLogger().info("Loading is started");
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
@ -103,7 +122,12 @@ public class TaskManager {
executorService.shutdownNow();
}
public synchronized Task getRunnableTask() {
/**
* @return Task - founded registered task with {@link Task#canRun()} = true;
* null - there is no available task found.
* @see Task#canRun()
*/
private synchronized Task getRunnableTask() {
if (!tasks.isEmpty()) {
for (Task t :
tasks) {
@ -116,6 +140,10 @@ public class TaskManager {
return null;
}
/**
* Makes the thread that is performing this method
* to wait until the loading is not done.
*/
private void waitForLoadingEnd() {
synchronized (this) {
while (!loadingDone.get()) {
@ -128,6 +156,11 @@ public class TaskManager {
}
}
/**
* @return a map where key is a thread making loading
* and where value is a task that is being performed by it
* at the moment.
*/
public Map<Thread, Task> getLoadersMonitorMap() {
return unmodifiableLoadersMonitorMap;
}