133 lines
3.8 KiB
Java
133 lines
3.8 KiB
Java
package eu.dnetlib.manager.wf.workflows.procs;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.concurrent.PriorityBlockingQueue;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import com.google.common.collect.BiMap;
|
|
import com.google.common.collect.HashBiMap;
|
|
|
|
import eu.dnetlib.errors.WorkflowManagerException;
|
|
import eu.dnetlib.manager.wf.workflows.util.WorkflowsConstants;
|
|
|
|
@Service
|
|
public class ProcessRegistry {
|
|
|
|
private static final Log log = LogFactory.getLog(ProcessRegistry.class);
|
|
private final BiMap<String, WorkflowProcess> procs = HashBiMap.create();
|
|
private final Map<String, Collection<WorkflowProcess>> byOtherId = new HashMap<>();
|
|
|
|
private final PriorityBlockingQueue<WorkflowProcess> pendingProcs = new PriorityBlockingQueue<>();
|
|
|
|
@Value("${'dnet.wf.registry.size'}")
|
|
private int maxSize;
|
|
|
|
synchronized public int countRunningWfs() {
|
|
int count = 0;
|
|
for (final Map.Entry<String, WorkflowProcess> e : this.procs.entrySet()) {
|
|
final WorkflowProcess proc = e.getValue();
|
|
if (!proc.isTerminated()) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public WorkflowProcess findProcess(final String procId) {
|
|
return this.procs.get(procId);
|
|
}
|
|
|
|
public Set<WorkflowProcess> listProcesses() {
|
|
return this.procs.values();
|
|
}
|
|
|
|
public Collection<WorkflowProcess> findProcsByOtherId(final String id) {
|
|
synchronized (this) {
|
|
final Collection<WorkflowProcess> res = this.byOtherId.get(id);
|
|
return res != null ? res : new ArrayList<>();
|
|
}
|
|
}
|
|
|
|
public String registerProcess(final WorkflowProcess process, final String... ids) throws WorkflowManagerException {
|
|
if (this.procs.containsValue(process) || this.procs.containsKey(process.getId())) {
|
|
log.error("Already registerd process: " + process);
|
|
throw new WorkflowManagerException("Already registerd process: " + process);
|
|
}
|
|
|
|
if (this.procs.size() >= this.maxSize) {
|
|
removeOldestProcess();
|
|
}
|
|
|
|
this.procs.put(process.getId(), process);
|
|
for (final String id : ids) {
|
|
synchronized (this) {
|
|
if (!this.byOtherId.containsKey(id)) {
|
|
this.byOtherId.put(id, new ArrayList<WorkflowProcess>());
|
|
}
|
|
this.byOtherId.get(id).add(process);
|
|
}
|
|
}
|
|
|
|
synchronized (this.pendingProcs) {
|
|
if (this.pendingProcs.size() > WorkflowsConstants.MAX_PENDING_PROCS_SIZE) {
|
|
log.warn("Wf [" + process.getName() + "] not launched, Max number of pending procs reached: " + WorkflowsConstants.MAX_PENDING_PROCS_SIZE);
|
|
throw new WorkflowManagerException("Max number of pending procs reached: " + WorkflowsConstants.MAX_PENDING_PROCS_SIZE);
|
|
}
|
|
this.pendingProcs.put(process);
|
|
|
|
log.info("WorkflowProcess [" + process + "] in queue, priority=" + process.getPriority());
|
|
}
|
|
|
|
return process.getId();
|
|
}
|
|
|
|
private void removeOldestProcess() {
|
|
LocalDateTime oldDate = LocalDateTime.now();
|
|
String oldId = null;
|
|
|
|
for (final Map.Entry<String, WorkflowProcess> e : this.procs.entrySet()) {
|
|
final WorkflowProcess proc = e.getValue();
|
|
|
|
if (proc.isTerminated()) {
|
|
final LocalDateTime date = proc.getLastActivityDate();
|
|
if (date.isBefore(oldDate)) {
|
|
oldDate = date;
|
|
oldId = e.getKey();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (oldId != null) {
|
|
unregisterProcess(oldId);
|
|
}
|
|
|
|
}
|
|
|
|
public void unregisterProcess(final String procId) {
|
|
synchronized (this) {
|
|
final WorkflowProcess process = this.procs.remove(procId);
|
|
if (process != null) {
|
|
for (final Collection<WorkflowProcess> processes : this.byOtherId.values()) {
|
|
processes.remove(process);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public WorkflowProcess nextProcessToStart() {
|
|
synchronized (this.pendingProcs) {
|
|
return this.pendingProcs.poll();
|
|
}
|
|
}
|
|
|
|
}
|