Skip to content

Commit

Permalink
Merge pull request #2060 from scireum/feature/sbi/SIRI-681
Browse files Browse the repository at this point in the history
Processes - Waiting State
  • Loading branch information
sabieber authored Dec 10, 2024
2 parents 5424099 + 71d615d commit 72c8ef8
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ protected boolean shouldExecutePartially() {
}

protected void executeInProcess(String factoryId, ProcessContext process) {
process.markRunning();
process.log(ProcessLog.info().withNLSKey("BatchProcessTaskExecutor.started"));
try {
jobs.findFactory(factoryId, BatchProcessJobFactory.class).executeTask(process);
Expand All @@ -76,6 +77,7 @@ protected void executeInProcess(String factoryId, ProcessContext process) {
}

protected void partiallyExecuteInProcess(String factoryId, ProcessContext process) {
process.markRunning();
process.log(ProcessLog.info().withNLSKey("BatchProcessTaskExecutor.started"));
Watch watch = Watch.start();
try {
Expand Down
38 changes: 37 additions & 1 deletion src/main/java/sirius/biz/process/Process.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,15 @@ public class Process extends SearchableEntity {
public static final Mapping ADMIN_TIMINGS = Mapping.named("adminTimings");
private final StringIntMap adminTimings = new StringIntMap();

/**
* Contains the timestamp when the process was created / initialized.
* <p>
* Note, for standby processes, this contains the timestamp of the last invocation.
*/
public static final Mapping CREATED = Mapping.named("created");
@NullAllowed
private LocalDateTime created;

/**
* Contains the timestamp when the process was started.
* <p>
Expand All @@ -220,6 +229,15 @@ public class Process extends SearchableEntity {
@NullAllowed
private LocalDateTime completed;

/**
* Contains the waiting time in seconds.
* <p>
* This is the time between the creation of the process and the actual start of the process.
*/
public static final Mapping WAITING_TIME = Mapping.named("waitingTime");
@NullAllowed
private int waitingTime;

/**
* Contains the estimated computation time performed in this process in seconds.
* <p>
Expand Down Expand Up @@ -387,7 +405,7 @@ public boolean shouldAutorefresh() {
*/
public String getStateColor() {
return switch (state) {
case RUNNING -> "blue";
case WAITING, RUNNING -> "blue";
case STANDBY -> "violet-light";
case TERMINATED -> "green";
case CANCELED -> "yellow";
Expand Down Expand Up @@ -589,6 +607,15 @@ public StringIntMap getAdminTimings() {
return adminTimings;
}

public LocalDateTime getCreated() {
return created;
}

public Process setCreated(LocalDateTime created) {
this.created = created;
return this;
}

public LocalDateTime getStarted() {
return started;
}
Expand Down Expand Up @@ -689,6 +716,15 @@ public void setWarnings(boolean warnings) {
this.warnings = warnings;
}

public int getWaitingTime() {
return waitingTime;
}

public Process setWaitingTime(int waitingTime) {
this.waitingTime = waitingTime;
return this;
}

public int getComputationTime() {
return computationTime;
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/sirius/biz/process/ProcessContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ public interface ProcessContext extends TaskContextAdapter {
*/
boolean isErroneous();

/**
* Marks the process as running.
*/
void markRunning();

/**
* Marks the process as completed.
* <p>
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/sirius/biz/process/ProcessEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ public boolean isErroneous() {
return processes.fetchProcess(processId).map(Process::isErrorneous).orElse(true);
}

@Override
public void markRunning() {
processes.markRunning(processId);
}

@Override
public void markCompleted(int computationTimeInSeconds) {
processes.reportLimitedMessages(processId, messageCountsPerType, limitsPerType);
Expand Down Expand Up @@ -325,7 +330,9 @@ public void cancel() {
@Override
public boolean isActive() {
return processes.fetchProcess(processId)
.map(proc -> proc.getState() == ProcessState.RUNNING || proc.getState() == ProcessState.STANDBY)
.map(process -> process.getState() == ProcessState.WAITING
|| process.getState() == ProcessState.RUNNING
|| process.getState() == ProcessState.STANDBY)
.orElse(false) && tasks.isRunning();
}

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/sirius/biz/process/ProcessState.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ public enum ProcessState {
*/
STANDBY,

/**
* Represents a process which is waiting for the execution to start.
* <p>
* This may be the case when the number of parallel processes is limited and the process is waiting for a slot.
*/
WAITING,

/**
* Represents a process which is actively running.
*/
Expand Down
35 changes: 29 additions & 6 deletions src/main/java/sirius/biz/process/Processes.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ public String createProcess(@Nullable String type,
process.setUserName(user.getUserName());
process.setTenantId(user.getTenantId());
process.setTenantName(user.getTenantName());
process.setState(ProcessState.RUNNING);
process.setState(ProcessState.WAITING);
process.setProcessType(type);
process.setStarted(LocalDateTime.now());
process.setCreated(LocalDateTime.now());
process.setPersistencePeriod(persistencePeriod);
process.getContext().modify().putAll(context);

Expand Down Expand Up @@ -399,6 +399,7 @@ private Process createStandbyProcessInLock(String type, String title, String ten
process.setTenantId(tenantId);
process.setTenantName(tenantName);
process.setState(ProcessState.STANDBY);
process.setCreated(LocalDateTime.now());
process.setStarted(LocalDateTime.now());
elastic.update(process);

Expand Down Expand Up @@ -503,6 +504,20 @@ protected boolean updateState(String processId, ProcessState newState) {
return modify(processId, null, process -> process.setState(newState));
}

/**
* Marks a process as running.
*
* @param processId the process to update
* @return <tt>true</tt> if the process was successfully modified, <tt>false</tt> otherwise
*/
protected boolean markRunning(String processId) {
return modify(processId, process -> process.getState() == ProcessState.WAITING, process -> {
process.setStarted(LocalDateTime.now());
process.setWaitingTime((int) Duration.between(process.getCreated(), process.getStarted()).getSeconds());
process.setState(ProcessState.RUNNING);
});
}

/**
* Marks a process as canceled.
* <p>
Expand All @@ -512,7 +527,9 @@ protected boolean updateState(String processId, ProcessState newState) {
* @return <tt>true</tt> if the process was successfully modified, <tt>false</tt> otherwise
*/
protected boolean markCanceled(String processId) {
return modify(processId, process -> process.getState() == ProcessState.RUNNING, process -> {
return modify(processId, process -> {
return process.getState() == ProcessState.WAITING || process.getState() == ProcessState.RUNNING;
}, process -> {
process.setErrorneous(true);
process.setCanceled(LocalDateTime.now());
process.setState(ProcessState.CANCELED);
Expand Down Expand Up @@ -557,7 +574,8 @@ protected boolean markWarnings(String processId) {
*/
protected boolean changeDebugging(String processId, boolean debuggingEnabled) {
return modify(processId,
process -> process.getState() == ProcessState.RUNNING
process -> process.getState() == ProcessState.WAITING
|| process.getState() == ProcessState.RUNNING
|| process.getState() == ProcessState.STANDBY,
process -> process.setDebugging(debuggingEnabled));
}
Expand Down Expand Up @@ -1003,7 +1021,11 @@ public void execute(String processId, Consumer<ProcessContext> task) {
*/
public boolean hasActiveProcesses() {
try {
return queryProcessesForCurrentUser().eq(Process.STATE, ProcessState.RUNNING).exists();
return queryProcessesForCurrentUser().where(elastic.filters()
.oneInField(Process.STATE,
List.of(ProcessState.WAITING,
ProcessState.RUNNING))
.build()).exists();
} catch (Exception exception) {
Exceptions.handle(Log.SYSTEM, exception);
return false;
Expand All @@ -1016,7 +1038,8 @@ public boolean hasActiveProcesses() {
* @return a query for all processes visible to the current user
*/
public ElasticQuery<Process> queryProcessesForCurrentUser() {
ElasticQuery<Process> query = elastic.select(Process.class).orderDesc(Process.STARTED);
ElasticQuery<Process> query =
elastic.select(Process.class).orderDesc(Process.CREATED).orderDesc(Process.STARTED);

UserInfo user = UserContext.getCurrentUser();
if (!user.hasPermission(ProcessController.PERMISSION_MANAGE_ALL_PROCESSES)) {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/biz_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ ProcessState.CANCELED = Abgebrochen
ProcessState.RUNNING = Aktiv
ProcessState.STANDBY = Standby
ProcessState.TERMINATED = Beendet
ProcessState.WAITING = In Warteschlange
Processes.messageLimitReached = Die Nachricht '${type}' trat insgesamt ${count} Mal auf. Für bessere Übersichtlichkeit wurden aber nur die ersten ${limit} Vorkommen aufgezeichnet.
Processes.restarted = Der Prozess wurde erneut gestartet: ${reason}
ProfileController.invalidOldPassword = Das alte Password ist inkorrekt.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<i:render name="header-actions"/>
</i:block>
<i:block name="additionalActions">
<i:if test="process.getState() == sirius.biz.process.ProcessState.RUNNING || process.getState() == sirius.biz.process.ProcessState.STANDBY">
<i:if test="process.getState() == sirius.biz.process.ProcessState.WAITING || process.getState() == sirius.biz.process.ProcessState.RUNNING || process.getState() == sirius.biz.process.ProcessState.STANDBY">
<i:if test="process.isDebugging()">
<t:dropdownItem labelKey="ProcessController.disableDebugging"
icon="fa-solid fa-bug-slash fa-fw"
Expand All @@ -63,7 +63,7 @@
</i:else>
</i:if>
</i:if>
<i:if test="process.getState() == sirius.biz.process.ProcessState.RUNNING">
<i:if test="process.getState() == sirius.biz.process.ProcessState.WAITING || process.getState() == sirius.biz.process.ProcessState.RUNNING">
<t:dropdownItem labelKey="NLS.cancel"
icon="fa-solid fa-ban fa-fw"
url="@apply('/ps/%s/cancel', process.getId())"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</i:block>

<i:block name="actions">
<i:if test="process.getState() == sirius.biz.process.ProcessState.RUNNING || process.getState() == sirius.biz.process.ProcessState.STANDBY">
<i:if test="process.getState() == sirius.biz.process.ProcessState.WAITING || process.getState() == sirius.biz.process.ProcessState.RUNNING || process.getState() == sirius.biz.process.ProcessState.STANDBY">
<i:local name="debugToggleUrl"
value="apply('/ps/%s/toggleDebugging', process.getId())"/>
<i:if test="process.isDebugging()">
Expand All @@ -54,7 +54,7 @@
</i:else>
</i:if>
</i:if>
<i:if test="process.getState() == sirius.biz.process.ProcessState.RUNNING">
<i:if test="process.getState() == sirius.biz.process.ProcessState.WAITING || process.getState() == sirius.biz.process.ProcessState.RUNNING">
<t:dropdownItem labelKey="NLS.cancel"
icon="fa-solid fa-ban fa-fw"
url="@apply('/ps/%s/cancel', process.getId())"
Expand Down

0 comments on commit 72c8ef8

Please sign in to comment.