Commitd7e754dfRecorded7 May 2026Repositorysigil-websocket

Enable WebSocket native test harness

Message

Add sigil-test and sigil-test-runner as dev dependencies so sigil-websocket can run its package-local native tests directly.

Move ws-receive after its private receive-message helper so the native path does not hit an unbound helper under the current toolchain.

Verification:

  • /home/daviwil/Projects/Code/sigil/sigil/build/dev/bin/sigil deps install --redirects ./dev-redirects.sgl
  • /home/daviwil/Projects/Code/sigil/sigil/build/dev/bin/sigil test --redirects ./dev-redirects.sgl
  • sh test/integration/test-wasm-websocket-client.sh
Changed
 package.sgl                        |  4 ++++
 src/sigil/websocket/connection.sgl | 96 ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------
 2 files changed, 52 insertions(+), 48 deletions(-)
Diff
package.sglmodified
@@ -34,6 +34,10 @@
34
(from-git url: "codeberg:sigil/sigil-tls" version: "^0.14.1")
35
(from-git url: "codeberg:sigil/sigil-crypto" version: "^0.15.0"))
36
+37
dev-dependencies: (list
+38
(from-git url: "codeberg:sigil/sigil-test" package: "sigil-test" version: "^0.16")
+39
(from-git url: "codeberg:sigil/sigil-test" package: "sigil-test-runner" version: "^0.16"))
+40
41
tasks: (list
42
(task
43
name: 'build
src/sigil/websocket/connection.sglmodified
@@ -388,54 +388,6 @@
388
(else
389
#f)))
390
391
;;; Receive a message (with async I/O support)
392
;;; Returns ws-message, 'closed, or #f on error
393
;;; When running in async scheduler, yields while waiting for data.
394
(define (ws-receive conn)
395
(: ws-connection? -> any?)
396
(if (not (ws-connected? conn))
397
'closed
398
(cond-expand
399
(wasm
400
(let ((result (process-wasm-event
401
conn
402
(conn-read (ws-connection-socket conn) 4096))))
403
(if (eq? result 'need-more)
404
#f
405
result)))
406
(else
407
(let ((socket (ws-connection-socket conn)))
408
(let loop ()
409
;; A prior socket read can contain multiple complete
410
;; WebSocket frames. Drain that buffer before waiting
411
;; for more readability; otherwise the async path can
412
;; block forever even though a frame is already local.
413
(let ((buffered
414
(let ((buffer (ws-connection-buffer conn)))
415
(if (> (bytevector-length buffer) 0)
416
(try-decode-message conn)
417
'need-more))))
418
(cond
419
((or (ws-message? buffered) (eq? buffered 'closed))
420
buffered)
421
((and buffered (not (eq? buffered 'need-more)))
422
#f)
423
(else
424
;; Wait for data (yields to scheduler if in async context)
425
(when (current-scheduler)
426
(await-readable socket))
427
;; Try to read and process
428
(let ((result (receive-message conn)))
429
(cond
430
;; Got a complete message or connection closed
431
((or (ws-message? result) (eq? result 'closed))
432
result)
433
;; Need more data - loop and wait again
434
((eq? result 'need-more)
435
(loop))
436
;; Error
437
(else #f)))))))))))))
438
391
;;; Internal: Read data and try to decode a message
392
;;; Returns ws-message, 'closed, 'need-more, or #f on error
393
(define (receive-message conn)
@@ -565,4 +517,52 @@
517
(else
518
'need-more))))
519
+520
;;; Receive a message (with async I/O support)
+521
;;; Returns ws-message, 'closed, or #f on error
+522
;;; When running in async scheduler, yields while waiting for data.
+523
(define (ws-receive conn)
+524
(: ws-connection? -> any?)
+525
(if (not (ws-connected? conn))
+526
'closed
+527
(cond-expand
+528
(wasm
+529
(let ((result (process-wasm-event
+530
conn
+531
(conn-read (ws-connection-socket conn) 4096))))
+532
(if (eq? result 'need-more)
+533
#f
+534
result)))
+535
(else
+536
(let ((socket (ws-connection-socket conn)))
+537
(let loop ()
+538
;; A prior socket read can contain multiple complete
+539
;; WebSocket frames. Drain that buffer before waiting
+540
;; for more readability; otherwise the async path can
+541
;; block forever even though a frame is already local.
+542
(let ((buffered
+543
(let ((buffer (ws-connection-buffer conn)))
+544
(if (> (bytevector-length buffer) 0)
+545
(try-decode-message conn)
+546
'need-more))))
+547
(cond
+548
((or (ws-message? buffered) (eq? buffered 'closed))
+549
buffered)
+550
((and buffered (not (eq? buffered 'need-more)))
+551
#f)
+552
(else
+553
;; Wait for data (yields to scheduler if in async context)
+554
(when (current-scheduler)
+555
(await-readable socket))
+556
;; Try to read and process
+557
(let ((result (receive-message conn)))
+558
(cond
+559
;; Got a complete message or connection closed
+560
((or (ws-message? result) (eq? result 'closed))
+561
result)
+562
;; Need more data - loop and wait again
+563
((eq? result 'need-more)
+564
(loop))
+565
;; Error
+566
(else #f)))))))))))))
+567
568
)