eyre: replace channel upon new GET request

As SSE are unidirectional, the client always realises that the
connection has failed faster than the server does. Hence, resuming a
subscription is useless, because channels can only be bound to one duct
at a time. Now, instead of failing a request for a channel
that is already bound to a duct, we replace the duct and continue
normally.
This commit is contained in:
Liam Fitzgerald 2021-06-24 10:24:55 +10:00
parent f0e11a8456
commit 9aaa44ff33
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
2 changed files with 19 additions and 10 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e0c05655f47ff81c8d4985a061d3ff57526a436adf25f667432a48c5cd10d438
size 12190347
oid sha256:9853dba422e06413e04c545a37f4a5eb92049000c30eedc8b56f23c82d484231
size 12392322

View File

@ -1206,15 +1206,24 @@
?~ maybe-channel=(~(get by session.channel-state.state) channel-id)
%^ return-static-data-on-duct 404 'text/html'
(error-page 404 %.y url.request ~)
:: if there's already a duct listening to this channel, we must 400
::
?: ?=([%| *] state.u.maybe-channel)
%^ return-static-data-on-duct 400 'text/html'
(error-page 400 %.y url.request "channel already bound")
:: when opening an event-stream, we must cancel our timeout timer
:: if there's no duct already bound. Else, kill the old request
:: and replace it
::
=. moves
[(cancel-timeout-move channel-id p.state.u.maybe-channel) moves]
=^ cancel-moves state
?. ?=([%| *] state.u.maybe-channel)
:_ state
(cancel-timeout-move channel-id p.state.u.maybe-channel)^~
=/ cancel-heartbeat
?~ heartbeat.u.maybe-channel ~
:_ ~
%+ cancel-heartbeat-move channel-id
[date duct]:u.heartbeat.u.maybe-channel
=- [(weld cancel-heartbeat -<) ->]
%. [%cancel ~]
%* . handle-response
duct p.state.u.maybe-channel
==
:: the request may include a 'Last-Event-Id' header
::
=/ maybe-last-event-id=(unit @ud)
@ -1283,7 +1292,7 @@
|= =channel
channel(events ~, state [%| duct], heartbeat (some [heartbeat-time duct]))
::
[[heartbeat (weld http-moves moves)] state]
[[heartbeat :(weld http-moves cancel-moves moves)] state]
:: +acknowledge-events: removes events before :last-event-id on :channel-id
::
++ acknowledge-events