Skip to content

Commit d9ce804

Browse files
Merge branch 'master' into add-listing-of-comp-runs
2 parents 9e58ce3 + e42e1a3 commit d9ce804

File tree

22 files changed

+346
-187
lines changed

22 files changed

+346
-187
lines changed

packages/models-library/src/models_library/api_schemas_rpc_async_jobs/async_jobs.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
from typing import Any, TypeAlias
1+
from typing import Annotated, Any, TypeAlias
22
from uuid import UUID
33

4-
from models_library.users import UserID
5-
from pydantic import BaseModel
4+
from pydantic import BaseModel, StringConstraints
65

6+
from ..products import ProductName
77
from ..progress_bar import ProgressReport
8+
from ..users import UserID
89

910
AsyncJobId: TypeAlias = UUID
11+
AsyncJobName: TypeAlias = Annotated[
12+
str, StringConstraints(strip_whitespace=True, min_length=1)
13+
]
1014

1115

1216
class AsyncJobStatus(BaseModel):
@@ -21,6 +25,7 @@ class AsyncJobResult(BaseModel):
2125

2226
class AsyncJobGet(BaseModel):
2327
job_id: AsyncJobId
28+
job_name: AsyncJobName
2429

2530

2631
class AsyncJobAbort(BaseModel):
@@ -31,5 +36,5 @@ class AsyncJobAbort(BaseModel):
3136
class AsyncJobNameData(BaseModel):
3237
"""Data for controlling access to an async job"""
3338

39+
product_name: ProductName
3440
user_id: UserID
35-
product_name: str

packages/service-library/tests/rabbitmq/test_rabbitmq_rpc_interfaces_async_jobs.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ async def list_jobs(
108108

109109
return [
110110
AsyncJobGet(
111-
job_id=TypeAdapter(AsyncJobId).validate_python(t.get_name())
111+
job_id=TypeAdapter(AsyncJobId).validate_python(t.get_name()),
112+
job_name="fake_job_name",
112113
)
113114
for t in self.tasks
114115
]
@@ -117,7 +118,7 @@ async def submit(self, job_id_data: AsyncJobNameData) -> AsyncJobGet:
117118
assert job_id_data
118119
job_id = faker.uuid4(cast_to=None)
119120
self.tasks.append(asyncio.create_task(_slow_task(), name=f"{job_id}"))
120-
return AsyncJobGet(job_id=job_id)
121+
return AsyncJobGet(job_id=job_id, job_name="fake_job_name")
121122

122123
async def setup(self) -> None:
123124
for m in (self.status, self.cancel, self.result):

services/static-webserver/client/source/class/osparc/data/PollTask.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ qx.Class.define("osparc.data.PollTask", {
3030
if (taskData && "task_id" in taskData) {
3131
this.set({
3232
taskId: taskData["task_id"],
33+
taskName: taskData["task_name"] || "",
3334
statusHref: taskData["status_href"],
34-
resultHref: taskData["result_href"]
35+
resultHref: taskData["result_href"],
3536
});
3637

3738
if ("abort_href" in taskData) {
@@ -64,6 +65,11 @@ qx.Class.define("osparc.data.PollTask", {
6465
nullable: false
6566
},
6667

68+
taskName: {
69+
check: "String",
70+
nullable: true
71+
},
72+
6773
statusHref: {
6874
check: "String",
6975
nullable: false

services/static-webserver/client/source/class/osparc/desktop/MainPage.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ qx.Class.define("osparc.desktop.MainPage", {
7979
flex: 1
8080
});
8181

82+
this.__attachTasks();
8283
this.__listenToWalletSocket();
8384
this.__attachHandlers();
8485
});
@@ -90,6 +91,14 @@ qx.Class.define("osparc.desktop.MainPage", {
9091
__loadingPage: null,
9192
__studyEditor: null,
9293

94+
__attachTasks: function() {
95+
const pollTasks = osparc.store.PollTasks.getInstance();
96+
const exportDataTasks = pollTasks.getExportDataTasks();
97+
exportDataTasks.forEach(task => {
98+
osparc.task.ExportData.exportDataTaskReceived(task, false);
99+
});
100+
},
101+
93102
__listenToWalletSocket: function() {
94103
const socket = osparc.wrapper.WebSocket.getInstance();
95104
if (!socket.slotExists("walletOsparcCreditsUpdated")) {

services/static-webserver/client/source/class/osparc/file/FileLabelWithActions.js

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ qx.Class.define("osparc.file.FileLabelWithActions", {
180180
const fetchPromise = dataStore.exportData(paths);
181181
const pollTasks = osparc.store.PollTasks.getInstance();
182182
pollTasks.createPollingTask(fetchPromise)
183-
.then(task => this.__exportDataTaskReceived(task))
183+
.then(task => osparc.task.ExportData.exportDataTaskReceived(task))
184184
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Unsuccessful files download")));
185185
},
186186

@@ -245,71 +245,6 @@ qx.Class.define("osparc.file.FileLabelWithActions", {
245245
}
246246
},
247247

248-
__exportDataTaskReceived: function(task) {
249-
const exportDataTaskUI = new osparc.task.ExportData();
250-
exportDataTaskUI.setTask(task);
251-
osparc.task.TasksContainer.getInstance().addTaskUI(exportDataTaskUI);
252-
253-
const progressWindow = new osparc.ui.window.Progress(
254-
this.tr("Downloading files"),
255-
"@FontAwesome5Solid/download/14",
256-
this.tr("Downloading files..."),
257-
);
258-
if (task.getAbortHref()) {
259-
const cancelButton = progressWindow.addCancelButton();
260-
cancelButton.setLabel(this.tr("Ignore"));
261-
const abortButton = new qx.ui.form.Button().set({
262-
label: this.tr("Cancel"),
263-
center: true,
264-
minWidth: 100,
265-
});
266-
abortButton.addListener("execute", () => task.abortRequested());
267-
progressWindow.addButton(abortButton);
268-
abortButton.set({
269-
appearance: "danger-button",
270-
});
271-
}
272-
progressWindow.open();
273-
274-
task.addListener("updateReceived", e => {
275-
const data = e.getData();
276-
if (data["task_progress"]) {
277-
if ("message" in data["task_progress"] && data["task_progress"]["message"]) {
278-
progressWindow.setMessage(data["task_progress"]["message"]);
279-
}
280-
progressWindow.setProgress(osparc.data.PollTask.extractProgress(data) * 100);
281-
}
282-
}, this);
283-
task.addListener("resultReceived", e => {
284-
const taskData = e.getData();
285-
if (taskData["result"]) {
286-
const params = {
287-
url: {
288-
locationId: 0,
289-
fileUuid: encodeURIComponent(taskData["result"]),
290-
}
291-
};
292-
osparc.data.Resources.fetch("storageLink", "getOne", params)
293-
.then(data => {
294-
if (data && data.link) {
295-
const fileName = taskData["result"].split("/").pop();
296-
osparc.utils.Utils.downloadLink(data.link, "GET", fileName);
297-
}
298-
})
299-
}
300-
progressWindow.close();
301-
});
302-
task.addListener("taskAborted", () => {
303-
osparc.FlashMessenger.logAs(this.tr("Download aborted"), "WARNING");
304-
progressWindow.close();
305-
});
306-
task.addListener("pollingError", e => {
307-
const err = e.getData();
308-
osparc.FlashMessenger.logError(err);
309-
progressWindow.close();
310-
});
311-
},
312-
313248
__deleteTaskReceived: function(task, paths) {
314249
const taskUI = new osparc.task.TaskUI();
315250
taskUI.setIcon("@FontAwesome5Solid/trash/14");

services/static-webserver/client/source/class/osparc/store/PollTasks.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ qx.Class.define("osparc.store.PollTasks", {
8383
return this.getTasks().filter(task => task.getTaskId().includes("from_study") && task.getTaskId().includes("as_template"));
8484
},
8585

86+
getExportDataTasks: function() {
87+
return this.getTasks().filter(task => task.getTaskName() && task.getTaskName() === "export_data");
88+
},
89+
8690
removeTasks: function() {
8791
const tasks = this.getTasks();
8892
tasks.forEach(task => task.dispose());

services/static-webserver/client/source/class/osparc/task/ExportData.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,77 @@ qx.Class.define("osparc.task.ExportData", {
2626
},
2727

2828
statics: {
29-
ICON: "@FontAwesome5Solid/download"
29+
ICON: "@FontAwesome5Solid/download",
30+
31+
exportDataTaskReceived: function(task, popUpProgressWindow = true) {
32+
const exportDataTaskUI = new osparc.task.ExportData();
33+
exportDataTaskUI.setTask(task);
34+
osparc.task.TasksContainer.getInstance().addTaskUI(exportDataTaskUI);
35+
36+
if (popUpProgressWindow) {
37+
const progressWindow = new osparc.ui.window.Progress(
38+
qx.locale.Manager.tr("Downloading files"),
39+
osparc.task.ExportData+"/14",
40+
qx.locale.Manager.tr("Compressing files..."),
41+
);
42+
43+
if (task.getAbortHref()) {
44+
const cancelButton = progressWindow.addCancelButton();
45+
cancelButton.setLabel(qx.locale.Manager.tr("Ignore"));
46+
const abortButton = new qx.ui.form.Button().set({
47+
label: qx.locale.Manager.tr("Cancel"),
48+
center: true,
49+
minWidth: 100,
50+
});
51+
abortButton.addListener("execute", () => task.abortRequested());
52+
progressWindow.addButton(abortButton);
53+
abortButton.set({
54+
appearance: "danger-button",
55+
});
56+
}
57+
58+
task.addListener("updateReceived", e => {
59+
const data = e.getData();
60+
if (data["task_progress"]) {
61+
if ("message" in data["task_progress"] && data["task_progress"]["message"]) {
62+
progressWindow.setMessage(data["task_progress"]["message"]);
63+
}
64+
progressWindow.setProgress(osparc.data.PollTask.extractProgress(data) * 100);
65+
}
66+
});
67+
68+
task.addListener("resultReceived", () => progressWindow.close());
69+
task.addListener("taskAborted", () => progressWindow.close());
70+
task.addListener("pollingError", () => progressWindow.close());
71+
72+
progressWindow.open();
73+
}
74+
75+
task.addListener("resultReceived", e => {
76+
const taskData = e.getData();
77+
if (taskData["result"]) {
78+
const params = {
79+
url: {
80+
locationId: 0,
81+
fileUuid: encodeURIComponent(taskData["result"]),
82+
}
83+
};
84+
osparc.data.Resources.fetch("storageLink", "getOne", params)
85+
.then(data => {
86+
if (data && data.link) {
87+
const fileName = taskData["result"].split("/").pop();
88+
osparc.utils.Utils.downloadLink(data.link, "GET", fileName);
89+
}
90+
})
91+
}
92+
});
93+
task.addListener("taskAborted", () => {
94+
osparc.FlashMessenger.logAs(qx.locale.Manager.tr("Download aborted"), "WARNING");
95+
});
96+
task.addListener("pollingError", e => {
97+
const err = e.getData();
98+
osparc.FlashMessenger.logError(err);
99+
});
100+
}
30101
},
31102
});

services/static-webserver/client/source/class/osparc/ui/window/Progress.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ qx.Class.define("osparc.ui.window.Progress", {
4444
control.getChildControl("progress").set({
4545
backgroundColor: "strong-main"
4646
});
47+
control.getContentElement().setStyles({
48+
"border-radius": "4px"
49+
});
4750
this.addAt(control, 1);
4851
break;
4952
}

services/storage/src/simcore_service_storage/api/_worker_tasks/_simcore_s3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async def _task_progress_cb(
2626
) -> None:
2727
worker = get_celery_worker(task.app)
2828
assert task.name # nosec
29-
await worker.set_progress(
29+
await worker.set_task_progress(
3030
task_id=task_id,
3131
report=report,
3232
)
@@ -87,7 +87,7 @@ async def export_data(
8787

8888
async def _progress_cb(report: ProgressReport) -> None:
8989
assert task.name # nosec
90-
await get_celery_worker(task.app).set_progress(task_id, report)
90+
await get_celery_worker(task.app).set_task_progress(task_id, report)
9191
_logger.debug("'%s' progress %s", task_id, report.percent_value)
9292

9393
async with ProgressBarData(

services/storage/src/simcore_service_storage/api/rest/_files.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
UploadLinks,
3636
)
3737
from ...modules.celery.client import CeleryTaskClient
38-
from ...modules.celery.models import TaskUUID
38+
from ...modules.celery.models import TaskMetadata, TaskUUID
3939
from ...simcore_s3_dsm import SimcoreS3DataManager
4040
from .._worker_tasks._files import complete_upload_file as remote_complete_upload_file
4141
from .dependencies.celery import get_celery_client
@@ -284,8 +284,10 @@ async def complete_upload_file(
284284
user_id=query_params.user_id,
285285
product_name=_UNDEFINED_PRODUCT_NAME_FOR_WORKER_TASKS, # NOTE: I would need to change the API here
286286
)
287-
task_uuid = await celery_client.send_task(
288-
remote_complete_upload_file.__name__,
287+
task_uuid = await celery_client.submit_task(
288+
TaskMetadata(
289+
name=remote_complete_upload_file.__name__,
290+
),
289291
task_context=async_job_name_data.model_dump(),
290292
user_id=async_job_name_data.user_id,
291293
location_id=location_id,

0 commit comments

Comments
 (0)