Skip to content

Commit 6764132

Browse files
committed
migrate list progress
1 parent 39d1750 commit 6764132

File tree

2 files changed

+10
-163
lines changed

2 files changed

+10
-163
lines changed

proc/misc/src/main/java/org/neo4j/gds/ListProgressProc.java

Lines changed: 9 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -19,189 +19,36 @@
1919
*/
2020
package org.neo4j.gds;
2121

22-
import org.apache.commons.lang3.time.DurationFormatUtils;
23-
import org.neo4j.gds.core.utils.ClockService;
24-
import org.neo4j.gds.core.utils.progress.JobId;
25-
import org.neo4j.gds.core.utils.progress.TaskStore;
26-
import org.neo4j.gds.core.utils.progress.tasks.DepthAwareTaskVisitor;
27-
import org.neo4j.gds.core.utils.progress.tasks.Task;
28-
import org.neo4j.gds.core.utils.progress.tasks.TaskTraversal;
29-
import org.neo4j.gds.procedures.operations.StructuredOutputHelper;
22+
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
23+
import org.neo4j.gds.procedures.operations.ProgressResult;
3024
import org.neo4j.procedure.Context;
3125
import org.neo4j.procedure.Description;
3226
import org.neo4j.procedure.Internal;
3327
import org.neo4j.procedure.Name;
3428
import org.neo4j.procedure.Procedure;
35-
import org.neo4j.values.storable.LocalTimeValue;
3629

37-
import java.time.Instant;
38-
import java.time.LocalTime;
39-
import java.time.ZoneId;
40-
import java.util.ArrayList;
41-
import java.util.List;
42-
import java.util.Map;
43-
import java.util.stream.Collectors;
4430
import java.util.stream.Stream;
4531

46-
import static org.neo4j.gds.utils.StringFormatting.formatWithLocale;
47-
48-
public class ListProgressProc extends BaseProc {
49-
static final int PROGRESS_BAR_LENGTH = 10;
32+
public class ListProgressProc {
5033
private static final String DESCRIPTION = "List progress events for currently running tasks.";
5134

5235
@Context
53-
public TaskStore taskStore;
36+
public GraphDataScienceProcedures facade;
5437

5538
@Internal
5639
@Deprecated(forRemoval = true)
5740
@Procedure(value = "gds.beta.listProgress", deprecatedBy = "gds.listProgress")
5841
@Description(DESCRIPTION)
59-
public Stream<ProgressResult> betaListProgress(
60-
@Name(value = "jobId", defaultValue = "") String jobId
61-
) {
62-
executionContext()
63-
.metricsFacade()
64-
.deprecatedProcedures().called("gds.beta.listProgress");
65-
66-
executionContext()
67-
.log()
68-
.warn("Procedure `gds.beta.listProgress` has been deprecated, please use `gds.listProgress`.");
42+
public Stream<ProgressResult> betaListProgress(@Name(value = "jobId", defaultValue = "") String jobId) {
43+
facade.deprecatedProcedures().called("gds.beta.listProgress");
44+
facade.log().warn("Procedure `gds.beta.listProgress` has been deprecated, please use `gds.listProgress`.");
6945

7046
return listProgress(jobId);
7147
}
7248

7349
@Procedure("gds.listProgress")
7450
@Description(DESCRIPTION)
75-
public Stream<ProgressResult> listProgress(
76-
@Name(value = "jobId", defaultValue = "") String jobId
77-
) {
78-
return jobId.isBlank()
79-
? jobsSummaryView()
80-
: jobDetailView(jobId);
81-
}
82-
83-
private Stream<ProgressResult> jobsSummaryView() {
84-
if (isGdsAdmin()) {
85-
return taskStore.query().map(ProgressResult::fromTaskStoreEntry);
86-
} else {
87-
return taskStore.query(username()).map(ProgressResult::fromTaskStoreEntry);
88-
}
89-
}
90-
91-
private Stream<ProgressResult> jobDetailView(String jobIdAsString) {
92-
var jobId = new JobId(jobIdAsString);
93-
94-
if (isGdsAdmin()) {
95-
var progressResults = taskStore
96-
.query(jobId)
97-
.flatMap(ListProgressProc::jobProgress)
98-
.collect(Collectors.toList());
99-
100-
if (progressResults.isEmpty()) {
101-
throw new IllegalArgumentException(formatWithLocale(
102-
"No task with job id `%s` was found.",
103-
jobIdAsString
104-
));
105-
}
106-
107-
return progressResults.stream();
108-
} else {
109-
return taskStore.query(username(), jobId).map(ListProgressProc::jobProgress).orElseThrow(
110-
() -> new IllegalArgumentException(formatWithLocale(
111-
"No task with job id `%s` was found.",
112-
jobIdAsString
113-
))
114-
);
115-
}
116-
}
117-
118-
private static Stream<ProgressResult> jobProgress(TaskStore.UserTask userTask) {
119-
var jobProgressVisitor = new JobProgressVisitor(userTask.jobId(), userTask.username());
120-
TaskTraversal.visitPreOrderWithDepth(userTask.task(), jobProgressVisitor);
121-
return jobProgressVisitor.progressRowsStream();
122-
}
123-
124-
@SuppressWarnings("unused")
125-
public static class ProgressResult {
126-
public String username;
127-
public String jobId;
128-
public String taskName;
129-
public String progress;
130-
public String progressBar;
131-
public String status;
132-
public LocalTimeValue timeStarted;
133-
public String elapsedTime;
134-
135-
static ProgressResult fromTaskStoreEntry(String username, Map.Entry<JobId, Task> taskStoreEntry) {
136-
var jobId = taskStoreEntry.getKey();
137-
var task = taskStoreEntry.getValue();
138-
return new ProgressResult(username, task, jobId, task.description());
139-
}
140-
141-
static ProgressResult fromTaskStoreEntry(TaskStore.UserTask userTask) {
142-
return new ProgressResult(userTask.username(), userTask.task(), userTask.jobId(), userTask.task().description());
143-
}
144-
145-
static ProgressResult fromTaskWithDepth(String username, Task task, JobId jobId, int depth) {
146-
var treeViewTaskName = StructuredOutputHelper.treeViewDescription(task.description(), depth);
147-
return new ProgressResult(username, task, jobId, treeViewTaskName);
148-
}
149-
150-
public ProgressResult(String username, Task task, JobId jobId, String taskName) {
151-
var progressContainer = task.getProgress();
152-
153-
this.jobId = jobId.asString();
154-
this.taskName = taskName;
155-
this.username = username;
156-
this.progress = StructuredOutputHelper.computeProgress(progressContainer);
157-
this.progressBar = StructuredOutputHelper.progressBar(progressContainer, PROGRESS_BAR_LENGTH);
158-
this.status = task.status().name();
159-
this.timeStarted = localTimeValue(task);
160-
this.elapsedTime = prettyElapsedTime(task);
161-
}
162-
163-
private LocalTimeValue localTimeValue(Task task) {
164-
if (task.hasNotStarted()) {
165-
return null;
166-
}
167-
return LocalTimeValue.localTime(LocalTime.ofInstant(
168-
Instant.ofEpochMilli(task.startTime()),
169-
ZoneId.systemDefault()
170-
));
171-
}
172-
173-
private String prettyElapsedTime(Task task) {
174-
if (task.hasNotStarted()) {
175-
return "Not yet started";
176-
}
177-
var finishTime = task.finishTime();
178-
var finishTimeOrNow = finishTime != -1
179-
? finishTime
180-
: ClockService.clock().millis();
181-
var elapsedTime = finishTimeOrNow - task.startTime();
182-
return DurationFormatUtils.formatDurationWords(elapsedTime, true, true);
183-
}
184-
}
185-
186-
public static class JobProgressVisitor extends DepthAwareTaskVisitor {
187-
188-
private final JobId jobId;
189-
private final String username;
190-
private final List<ProgressResult> progressRows;
191-
192-
JobProgressVisitor(JobId jobId, String username) {
193-
this.jobId = jobId;
194-
this.username = username;
195-
this.progressRows = new ArrayList<>();
196-
}
197-
198-
Stream<ProgressResult> progressRowsStream() {
199-
return this.progressRows.stream();
200-
}
201-
202-
@Override
203-
public void visit(Task task) {
204-
progressRows.add(ProgressResult.fromTaskWithDepth(username, task, jobId, depth()));
205-
}
51+
public Stream<ProgressResult> listProgress(@Name(value = "jobId", defaultValue = "") String jobId) {
52+
return facade.operations().listProgress(jobId);
20653
}
20754
}

procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/DefaultResultRenderer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private IllegalArgumentException createException() {
5959
return new IllegalArgumentException(
6060
formatWithLocale(
6161
"No task with job id `%s` was found.",
62-
jobId
62+
jobId.asString()
6363
)
6464
);
6565
}

0 commit comments

Comments
 (0)