Skip to content

Commit 3a3355b

Browse files
committed
fix: http-based session message inorder in slow network
1 parent a5e50b6 commit 3a3355b

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

pywebio/platform/adaptor/http.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class HttpHandler:
113113
"""
114114
# type: Dict[str, Session]
115115
_webio_sessions = {} # WebIOSessionID -> WebIOSession()
116+
_webio_last_commands = {} # WebIOSessionID -> (last commands, commands sequence id)
116117
_webio_expire = LRUDict() # WebIOSessionID -> last active timestamp. In increasing order of last active time
117118
_webio_expire_lock = threading.Lock()
118119

@@ -149,6 +150,17 @@ def _remove_webio_session(cls, sid):
149150
cls._webio_sessions.pop(sid, None)
150151
cls._webio_expire.pop(sid, None)
151152

153+
@classmethod
154+
def get_response(cls, sid, ack=0):
155+
commands, seq = cls._webio_last_commands.get(sid, ([], 0))
156+
if ack == seq:
157+
webio_session = cls._webio_sessions[sid]
158+
commands = webio_session.get_task_commands()
159+
seq += 1
160+
cls._webio_last_commands[sid] = (commands, seq)
161+
162+
return {'commands': commands, 'seq': seq}
163+
152164
def _process_cors(self, context: HttpContext):
153165
"""Handling cross-domain requests: check the source of the request and set headers"""
154166
origin = context.request_headers().get('Origin', '')
@@ -272,7 +284,8 @@ def handle_request_context(self, context: HttpContext):
272284

273285
self.interval_cleaning()
274286

275-
context.set_content(webio_session.get_task_commands(), json_type=True)
287+
ack = int(context.request_url_parameter('ack', 0))
288+
context.set_content(type(self).get_response(webio_session_id, ack=ack), json_type=True)
276289

277290
if webio_session.closed():
278291
self._remove_webio_session(webio_session_id)

webiojs/src/session.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export class HttpSession implements Session {
181181
webio_session_id: string = 'NEW';
182182
debug = false;
183183

184+
private _executed_command_msg_id = 0;
184185
private _closed = false;
185186
private _session_create_callbacks: (() => void)[] = [];
186187
private _session_close_callbacks: (() => void)[] = [];
@@ -218,11 +219,11 @@ export class HttpSession implements Session {
218219
let that = this;
219220
$.ajax({
220221
type: "GET",
221-
url: this.api_url,
222+
url: `${this.api_url}&ack=${this._executed_command_msg_id}`,
222223
contentType: "application/json; charset=utf-8",
223224
dataType: "json",
224225
headers: {"webio-session-id": this.webio_session_id},
225-
success: function (data: Command[], textStatus: string, jqXHR: JQuery.jqXHR) {
226+
success: function (data: { commands: Command[], seq: number }, textStatus: string, jqXHR: JQuery.jqXHR) {
226227
safe_poprun_callbacks(that._session_create_callbacks, 'session_create_callback');
227228
that._on_request_success(data, textStatus, jqXHR);
228229
},
@@ -232,11 +233,16 @@ export class HttpSession implements Session {
232233
})
233234
}
234235

235-
private _on_request_success(data: Command[], textStatus: string, jqXHR: JQuery.jqXHR) {
236+
private _on_request_success(data: { commands: Command[], seq: number }, textStatus: string, jqXHR: JQuery.jqXHR) {
237+
if (data.seq == this._executed_command_msg_id)
238+
return;
239+
this._executed_command_msg_id = data.seq;
240+
236241
let sid = jqXHR.getResponseHeader('webio-session-id');
237-
if (sid) this.webio_session_id = sid;
242+
if (sid)
243+
this.webio_session_id = sid;
238244

239-
for (let msg of data) {
245+
for (let msg of data.commands) {
240246
if (this.debug) console.info('>>>', msg);
241247
this._on_server_message(msg);
242248
}
@@ -267,7 +273,7 @@ export class HttpSession implements Session {
267273
$.ajax({
268274
...options,
269275
type: "POST",
270-
url: this.api_url,
276+
url: `${this.api_url}&ack=${this._executed_command_msg_id}`,
271277
dataType: "json",
272278
headers: {"webio-session-id": this.webio_session_id},
273279
success: this._on_request_success.bind(this),

0 commit comments

Comments
 (0)