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 { 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> meta = new HashMap<>();
private final Map<String, String> unmodifiableMeta = Collections.unmodifiableMap(meta); 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) { public Module(String id) {
super(id); super(id);
meta.put("id", id); meta.put("id", id);
} }
/**
* @return meta information of the module as {@link Map}.
*/
public Map<String, String> getMeta() { public Map<String, String> getMeta() {
return unmodifiableMeta; return unmodifiableMeta;
} }
public List<Task> getTasks() { public Set<Task> getTasks() {
return tasks; 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) { public void addTask(Task task) {
task.setOwner(this); task.setOwner(this);
tasks.add(task); 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 ru.windcorp.progressia.common.util.namespaces.Namespaced;
import java.util.ArrayList; 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 public abstract class Task
extends Namespaced extends Namespaced
implements Runnable { implements Runnable {
List<Task> requiredTasks = new ArrayList<>(); private final Set<Task> requiredTasks = new HashSet<>();
private boolean isDone = false; private final AtomicBoolean isDone = new AtomicBoolean(false);
private boolean isActive = false; private final AtomicBoolean isActive = new AtomicBoolean(false);
private Module owner; 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) { public Task(String id) {
super(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) { public Task(String id, Module module) {
this(id); this(id);
module.addTask(this); module.addTask(this);
@ -59,32 +72,44 @@ public abstract class Task
throw CrashReports.report(new Throwable(), throw CrashReports.report(new Throwable(),
"The task cannot be performed second time"); "The task cannot be performed second time");
} else { } else {
isActive = true; isActive.set(true);
perform(); 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(); protected abstract void perform();
public boolean isDone() { 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() { 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() { public boolean canRun() {
if (this.isActive) return false; if (this.isActive.get() || isDone.get()) return false;
for (Task reqT : requiredTasks) { for (Task reqT : requiredTasks) {
if (!reqT.isDone()) return false; if (!reqT.isDone()) return false;
} }
return true; return true;
} }
public List<Task> getRequiredTasks() { public Set<Task> getRequiredTasks() {
return requiredTasks; return requiredTasks;
} }
@ -92,14 +117,21 @@ public abstract class Task
requiredTasks.add(task); requiredTasks.add(task);
} }
/**
* @return the module the task is attached to.
*/
public Module getOwner() { public Module getOwner() {
return owner; 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) { public void setOwner(Module module) {
if (owner != null) { if (owner != null) {
CrashReports.crash( 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.", , "Could not set %s as owner of %s, because %s is already owner of it.",
module.getId(), this.getId(), this.getOwner().getId()); module.getId(), this.getId(), this.getOwner().getId());
} else { } else {

View File

@ -53,15 +53,34 @@ public class TaskManager {
return instance; 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) { public void registerModule(Module module) {
tasks.addAll(module.getTasks()); tasks.addAll(module.getTasks());
modules.add(module); 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() { public boolean isLoadingDone() {
return loadingDone.get(); return loadingDone.get();
} }
/**
* The method to start loading. It will perform every registered task.
*/
public void startLoading() { public void startLoading() {
LogManager.getLogger().info("Loading is started"); LogManager.getLogger().info("Loading is started");
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
@ -103,7 +122,12 @@ public class TaskManager {
executorService.shutdownNow(); 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()) { if (!tasks.isEmpty()) {
for (Task t : for (Task t :
tasks) { tasks) {
@ -116,6 +140,10 @@ public class TaskManager {
return null; return null;
} }
/**
* Makes the thread that is performing this method
* to wait until the loading is not done.
*/
private void waitForLoadingEnd() { private void waitForLoadingEnd() {
synchronized (this) { synchronized (this) {
while (!loadingDone.get()) { 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() { public Map<Thread, Task> getLoadersMonitorMap() {
return unmodifiableLoadersMonitorMap; return unmodifiableLoadersMonitorMap;
} }