Skip to content

Commit f56bca3

Browse files
authored
Web Worker takes care of setting intervals for heartbeat (#1956)
* Update WatchDog.js * testing timer in Web Worker * timer4Worker -> pacemaker * changed heartbeat interval sent to client
1 parent d1f16d8 commit f56bca3

File tree

4 files changed

+57
-22
lines changed

4 files changed

+57
-22
lines changed

services/web/client/Manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"externalResources": {
2424
"script": [
2525
"socketio/socket.io.js",
26+
"osparc/pacemaker.js",
2627
"svg/svg.js",
2728
"svg/svg.path.js",
2829
"jsondiffpatch/jsondiffpatch.min.js",

services/web/client/source/class/osparc/io/WatchDog.js

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
1616
************************************************************************ */
1717

18+
/**
19+
* @asset(pacemaker.js)
20+
* @ignore(Worker)
21+
*/
22+
1823
/**
1924
* Singleton class that does some network connection checks.
2025
*
@@ -33,27 +38,21 @@
3338

3439
qx.Class.define("osparc.io.WatchDog", {
3540
extend: qx.core.Object,
36-
37-
type : "singleton",
41+
type: "singleton",
3842

3943
construct: function() {
40-
this.__clientHeartbeatPinger = new qx.event.Timer(this.heartbeatInterval);
41-
this.__clientHeartbeatPinger.addListener("interval", function() {
42-
const socket = osparc.wrapper.WebSocket.getInstance();
43-
try {
44-
socket.emit("client_heartbeat");
45-
} catch (error) {
46-
// no need to handle the error, nor does it need to cause further issues
47-
// it is ok to eat it up
48-
}
49-
}, this);
44+
this.__clientHeartbeatWWPinger = new Worker("resource/osparc/pacemaker.js");
45+
this.__clientHeartbeatWWPinger.onmessage = () => {
46+
this.__pingServer();
47+
};
5048

5149
// register for socket.io event to change the default heartbeat interval
5250
const socket = osparc.wrapper.WebSocket.getInstance();
5351
const socketIoEventName = "set_heartbeat_emit_interval";
5452
socket.removeSlot(socketIoEventName);
55-
socket.on(socketIoEventName, function(emitIntervalSeconds) {
56-
this.setHeartbeatInterval(parseInt(emitIntervalSeconds) * 1000);
53+
socket.on(socketIoEventName, emitIntervalSeconds => {
54+
const newInterval = parseInt(emitIntervalSeconds) * 1000;
55+
this.setHeartbeatInterval(newInterval);
5756
}, this);
5857
},
5958

@@ -74,18 +73,33 @@ qx.Class.define("osparc.io.WatchDog", {
7473
},
7574

7675
members: {
77-
__clientHeartbeatPinger: null,
76+
__clientHeartbeatWWPinger: null,
7877

7978
_applyOnLine: function(value) {
8079
let logo = osparc.component.widget.LogoOnOff.getInstance();
8180
if (logo) {
8281
logo.setOnLine(value);
8382
}
84-
value ? this.__clientHeartbeatPinger.start() : this.__clientHeartbeatPinger.stop();
83+
84+
if (value) {
85+
this.__clientHeartbeatWWPinger.postMessage(["start", this.getHeartbeatInterval()]);
86+
} else {
87+
this.__clientHeartbeatWWPinger.postMessage(["stop"]);
88+
}
8589
},
8690

8791
_applyHeartbeatInterval: function(value) {
88-
this.__clientHeartbeatPinger.setInterval(value);
92+
this.__clientHeartbeatWWPinger.postMessage(["start", value]);
93+
},
94+
95+
__pingServer: function() {
96+
const socket = osparc.wrapper.WebSocket.getInstance();
97+
try {
98+
socket.emit("client_heartbeat");
99+
} catch (error) {
100+
// no need to handle the error, nor does it need to cause further issues
101+
// it is ok to eat it up
102+
}
89103
}
90-
} // members
104+
}
91105
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
onmessage = e => {
2+
const action = e.data[0];
3+
switch (action) {
4+
case "start": {
5+
if (this.__timer) {
6+
clearInterval(this.__timer);
7+
}
8+
const newInterval = e.data[1];
9+
this.__timer = setInterval(() => {
10+
postMessage("interval");
11+
}, newInterval);
12+
break;
13+
}
14+
case "stop":
15+
if (this.__timer) {
16+
clearInterval(this.__timer);
17+
}
18+
break;
19+
}
20+
};

services/web/server/src/simcore_service_webserver/socketio/handlers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
from ..groups_api import list_user_groups
2020
from ..login.decorators import RQT_USERID_KEY, login_required
21-
from ..resource_manager.config import get_service_deletion_timeout
2221
from ..resource_manager.websocket_manager import managed_resource
2322
from .config import get_socket_server
2423
from .events import post_messages
@@ -53,9 +52,10 @@ async def connect(sid: str, environ: Dict, app: web.Application) -> bool:
5352
raise SocketIOConnectionError(f"Unexpected error: {exc}") from exc
5453

5554
# Send service_deletion_timeout to client
56-
# the interval should be < get_service_deletion_timeout(app) to avoid
57-
# issues, assuming half of the interval and not less the 2 seconds
58-
emit_interval: int = max(2, get_service_deletion_timeout(app) // 2)
55+
# 2 seconds avoids GC from removing the services to early
56+
# this has been tested and is working with good results
57+
# the previous implementation was not working as expected
58+
emit_interval: int = 2
5959
log.info("Sending set_heartbeat_emit_interval with %s", emit_interval)
6060

6161
user_id = request.get(RQT_USERID_KEY, ANONYMOUS_USER_ID)

0 commit comments

Comments
 (0)