Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ class OutputStatus(StrAutoEnum):
UPLOAD_STARTED = auto()
UPLOAD_WAS_ABORTED = auto()
UPLOAD_FINISHED_SUCCESSFULLY = auto()
UPLOAD_FINISHED_WITH_ERRROR = auto()
UPLOAD_FINISHED_WITH_ERROR = auto()


class InputStatus(StrAutoEnum):
DOWNLOAD_STARTED = auto()
DOWNLOAD_WAS_ABORTED = auto()
DOWNLOAD_FINISHED_SUCCESSFULLY = auto()
DOWNLOAD_FINISHED_WITH_ERRROR = auto()
DOWNLOAD_FINISHED_WITH_ERROR = auto()


class _PortStatusCommon(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async def send_output_port_upload_finished_with_error(
self, port_key: ServicePortKey
) -> None:
await self._send_output_port_status(
port_key, OutputStatus.UPLOAD_FINISHED_WITH_ERRROR
port_key, OutputStatus.UPLOAD_FINISHED_WITH_ERROR
)

async def send_input_port_download_started(self, port_key: ServicePortKey) -> None:
Expand All @@ -74,5 +74,5 @@ async def send_input_port_download_finished_with_error(
self, port_key: ServicePortKey
) -> None:
await self._send_input_port_status(
port_key, InputStatus.DOWNLOAD_FINISHED_WITH_ERRROR
port_key, InputStatus.DOWNLOAD_FINISHED_WITH_ERROR
)
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ async def test_notifier_send_input_port_status(
await port_notifier.send_input_port_download_finished_succesfully(
port_key
)
case InputStatus.DOWNLOAD_FINISHED_WITH_ERRROR:
case InputStatus.DOWNLOAD_FINISHED_WITH_ERROR:
await port_notifier.send_input_port_download_finished_with_error(
port_key
)
Expand Down Expand Up @@ -378,7 +378,7 @@ async def test_notifier_send_output_port_status(
await port_notifier.send_output_port_upload_finished_successfully(
port_key
)
case OutputStatus.UPLOAD_FINISHED_WITH_ERRROR:
case OutputStatus.UPLOAD_FINISHED_WITH_ERROR:
await port_notifier.send_output_port_upload_finished_with_error(
port_key
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ qx.Class.define("osparc.data.model.IframeHandler", {
this.setStudy(study);
this.setNode(node);

node.getStatus().addListener("changeInteractive", e => {
const newStatus = e.getData();
const oldStatus = e.getOldData();
this.__statusInteractiveChanged(newStatus, oldStatus);
});

this.__initLoadingPage();
this.__initIFrame();
},
Expand Down Expand Up @@ -51,12 +57,6 @@ qx.Class.define("osparc.data.model.IframeHandler", {
check: "osparc.widget.PersistentIframe",
init: null,
nullable: true
},

polling: {
check: "Boolean",
init: null,
nullable: true
}
},

Expand All @@ -69,12 +69,7 @@ qx.Class.define("osparc.data.model.IframeHandler", {
__stopRequestingStatus: null,
__retriesLeft: null,

startPolling: function() {
if (this.isPolling()) {
return;
}
this.setPolling(true);

checkState: function() {
this.getNode().getStatus().getProgressSequence()
.resetSequence();

Expand All @@ -87,7 +82,7 @@ qx.Class.define("osparc.data.model.IframeHandler", {
.resetSequence();

this.__unresponsiveRetries = 5;
this.__nodeState(false);
this.__nodeState();

this.getIFrame().resetSource();
},
Expand Down Expand Up @@ -124,47 +119,27 @@ qx.Class.define("osparc.data.model.IframeHandler", {
});
loadingPage.addExtraWidget(sequenceWidget);

nodeStatus.addListener("changeInteractive", () => {
loadingPage.setHeader(this.__getLoadingPageHeader());
const status = nodeStatus.getInteractive();
if (["idle", "failed"].includes(status)) {
const startButton = new qx.ui.form.Button().set({
label: this.tr("Start"),
icon: "@FontAwesome5Solid/play/18",
font: "text-18",
allowGrowX: false,
height: 32
});
startButton.addListener("execute", () => node.requestStartNode());
loadingPage.addWidgetToMessages(startButton);
} else {
loadingPage.setMessages([]);
}
}, this);
this.setLoadingPage(loadingPage);
},

__getLoadingPageHeader: function() {
__getLoadingPageHeader: function(status) {
const node = this.getNode();
let statusText = this.tr("Starting");
const status = node.getStatus().getInteractive();
if (status) {
statusText = status.charAt(0).toUpperCase() + status.slice(1);
if (status === undefined) {
status = node.getStatus().getInteractive();
}
const statusText = status ? (status.charAt(0).toUpperCase() + status.slice(1)) : this.tr("Starting");
const metadata = node.getMetaData();
const versionDisplay = osparc.service.Utils.extractVersionDisplay(metadata);
return statusText + " " + node.getLabel() + " <span style='font-size: 16px;font-weight: normal;'><sub>v" + versionDisplay + "</sub></span>";
},

__nodeState: function(starting=true) {
__nodeState: function() {
// Check if study is still there
if (this.getStudy() === null || this.__stopRequestingStatus === true) {
this.setPolling(false);
return;
}
// Check if node is still there
if (this.getStudy().getWorkbench().getNode(this.getNode().getNodeId()) === null) {
this.setPolling(false);
return;
}

Expand All @@ -176,7 +151,7 @@ qx.Class.define("osparc.data.model.IframeHandler", {
}
};
osparc.data.Resources.fetch("studies", "getNode", params)
.then(data => this.__onNodeState(data, starting))
.then(data => this.onNodeState(data))
.catch(err => {
let errorMsg = `Error retrieving ${node.getLabel()} status: ${err}`;
if ("status" in err && err.status === 406) {
Expand All @@ -191,7 +166,6 @@ qx.Class.define("osparc.data.model.IframeHandler", {
};
node.fireDataEvent("showInLogger", errorMsgData);
if ("status" in err && err.status === 406) {
this.setPolling(false);
return;
}
if (this.__unresponsiveRetries > 0) {
Expand All @@ -203,32 +177,24 @@ qx.Class.define("osparc.data.model.IframeHandler", {
};
node.fireDataEvent("showInLogger", retryMsgData);
this.__unresponsiveRetries--;
const interval = Math.floor(Math.random() * 5000) + 3000;
setTimeout(() => this.__nodeState(), interval);
} else {
this.setPolling(false);
node.getStatus().setInteractive("failed");
osparc.FlashMessenger.getInstance().logAs(this.tr("There was an error starting") + " " + node.getLabel(), "ERROR");
}
});
},

__onNodeState: function(data, starting=true) {
onNodeState: function(data) {
const serviceState = data["service_state"];
const nodeId = data["service_uuid"];
const node = this.getNode();
const status = node.getStatus();
let nextPollIn = null;
let pollingInNextStage = null;
switch (serviceState) {
case "idle": {
status.setInteractive(serviceState);
if (starting && this.__unresponsiveRetries>0) {
if (this.__unresponsiveRetries>0) {
// a bit of a hack. We will get rid of it when the backend pushes the states
this.__unresponsiveRetries--;
nextPollIn = 2000;
} else {
this.setPolling(false);
}
break;
}
Expand All @@ -248,36 +214,32 @@ qx.Class.define("osparc.data.model.IframeHandler", {
node.fireDataEvent("showInLogger", msgData);
}
status.setInteractive(serviceState);
nextPollIn = 10000;
break;
}
case "stopping":
case "unknown":
case "starting":
case "pulling": {
status.setInteractive(serviceState);
nextPollIn = 5000;
break;
}
case "running": {
if (nodeId !== node.getNodeId()) {
break;
}
if (!starting) {
status.setInteractive("stopping");
nextPollIn = 5000;
break;
}
const {
srvUrl,
isDynamicV2
} = osparc.utils.Utils.computeServiceUrl(data);
node.setDynamicV2(isDynamicV2);
if (srvUrl) {
if (
srvUrl &&
srvUrl !== node.getServiceUrl() // if it's already connected, do not restart the connection process
) {
this.__statusInteractiveChanged("connecting", node.getStatus().getInteractive());
this.__retriesLeft = 40;
this.__waitForServiceReady(srvUrl);
}
pollingInNextStage = true;
break;
}
case "complete":
Expand All @@ -297,18 +259,10 @@ qx.Class.define("osparc.data.model.IframeHandler", {
console.error(serviceState, "service state not supported");
break;
}
if (nextPollIn) {
qx.event.Timer.once(() => this.__nodeState(starting), this, nextPollIn);
} else if (pollingInNextStage !== true) {
this.setPolling(false);
}
},

__waitForServiceReady: function(srvUrl) {
this.getNode().getStatus().setInteractive("connecting");

if (this.__retriesLeft === 0) {
this.setPolling(false);
return;
}

Expand All @@ -317,7 +271,6 @@ qx.Class.define("osparc.data.model.IframeHandler", {

// Check if node is still there
if (this.getStudy().getWorkbench().getNode(this.getNode().getNodeId()) === null) {
this.setPolling(false);
return;
}
const interval = 5000;
Expand All @@ -335,7 +288,6 @@ qx.Class.define("osparc.data.model.IframeHandler", {
console.log("Connecting: fetch's response status", response.status);
}
if (response.status < 400) {
this.setPolling(false);
this.__serviceReadyIn(srvUrl);
} else {
console.log(`Connecting: ${srvUrl} is not reachable. Status: ${response.status}`);
Expand All @@ -356,16 +308,57 @@ qx.Class.define("osparc.data.model.IframeHandler", {
const node = this.getNode();
node.setServiceUrl(srvUrl);
node.getStatus().setInteractive("ready");
const msg = "Service ready on " + srvUrl;
const msgData = {
nodeId: node.getNodeId(),
msg,
level: "INFO"
};
node.fireDataEvent("showInLogger", msgData);
this.__restartIFrame();
if (!node.isDynamicV2()) {
node.callRetrieveInputs();
},

__statusInteractiveChanged: function(status, oldStatus) {
if (status === oldStatus) {
return;
}

const node = this.getNode();

const loadingPage = node.getLoadingPage();
loadingPage.setHeader(this.__getLoadingPageHeader(status));
loadingPage.clearMessages();
if (["idle", "failed"].includes(status)) {
const startButton = new qx.ui.form.Button().set({
label: this.tr("Start"),
icon: "@FontAwesome5Solid/play/18",
font: "text-18",
allowGrowX: false,
height: 32
});
startButton.addListener("execute", () => node.requestStartNode());
loadingPage.addWidgetToMessages(startButton);
}

if (status === "ready") {
const msg = `Service ${node.getLabel()} ${status}`;
const msgData = {
nodeId: node.getNodeId(),
msg,
level: "INFO"
};
node.fireDataEvent("showInLogger", msgData);

// will switch to iframe's content
this.__restartIFrame();
if (!node.isDynamicV2()) {
node.callRetrieveInputs();
}
} else if (["idle", "failed", "stopping"].includes(status) && oldStatus) {
const msg = `Service ${node.getLabel()} ${status}`;
const msgData = {
nodeId: node.getNodeId(),
msg,
level: "INFO"
};
node.fireDataEvent("showInLogger", msgData);

// will switch to the loading page
node.resetServiceUrl();
this.getIFrame().resetSource();
this.fireEvent("iframeChanged");
}
},

Expand Down Expand Up @@ -394,7 +387,7 @@ qx.Class.define("osparc.data.model.IframeHandler", {
const node = this.getNode();
const status = node.getStatus().getInteractive();
// it might have been stopped
if (status === "ready") {
if (["running", "ready"].includes(status)) {
this.getIFrame().resetSource();
this.getIFrame().setSource(node.getServiceUrl());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ qx.Class.define("osparc.data.model.Node", {
}
};
osparc.data.Resources.fetch("studies", "startNode", params)
.then(() => this.startPollingState())
.then(() => this.checkState())
.catch(err => {
if ("status" in err && (err.status === 409 || err.status === 402)) {
osparc.FlashMessenger.getInstance().logAs(err.message, "WARNING");
Expand Down Expand Up @@ -1055,7 +1055,7 @@ qx.Class.define("osparc.data.model.Node", {
}
},

startPollingState: function() {
checkState: function() {
if (this.isDynamic()) {
const metadata = this.getMetaData();
const msg = "Starting " + metadata.key + ":" + metadata.version + "...";
Expand All @@ -1067,7 +1067,7 @@ qx.Class.define("osparc.data.model.Node", {
this.fireDataEvent("showInLogger", msgData);

if (this.getIframeHandler()) {
this.getIframeHandler().startPolling();
this.getIframeHandler().checkState();
} else {
console.error(this.getLabel() + " iframe handler not ready");
}
Expand Down
Loading
Loading