This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
[🐞 ✨] the future of server-side resumability(action$(...)
, server$(...)
, etc ...
#91
Labels
[STAGE-2] incomplete implementation
Remove this label when implementation is complete
[STAGE-2] not fully covered by tests yet
Remove this label when tests are verified to cover the implementation
[STAGE-2] unresolved discussions left
Remove this label when all critical discussions are resolved on the issue
[STAGE-3] docs changes not added yet
Remove this label when the necessary documentation for the feature / change is added
[STAGE-3] missing 2 reviews for RFC PRs
Remove this label when at least 2 core team members reviewed and approved the RFC implementation
Is your feature request related to a problem?
I'm using qwik 0.19.2, qwik-city 0.4.0, latest version as of writing
qwik recently introduced
server$(...)
, along with the already existingaction$(...)
Iet's focus on
server$(...)
first, because I think that is where the future is headed :)it currently has the following problems:
let
toconst
when capturing scoped values, so it's actually not really a server-side function, it may be called a server-side class, all it's state is still serialized to and coming back from the client, no server-side state, just a syntactic sugar around XHRbut as for now I didn't fully understand how this new
server$(...)
thing works internally, so I may be wrong. and I've seen somewhere else forget where, that (manucorporat) mentioned there are still some serialization problems, maybe that can be fixed(though I highly doubt that under the current architectureserver$(...)
is still a endpoint like request/response http thing, if you really think about it, it's just syntactic sugar around jsonp. we didn't really bringserver-side resumability
to the table, more on what I mean at the end of the articlewhy I'm not talking about
action$(...)
?in my opinion, it has many fatal design flaws, even compared to
server$(...)
from the source code,
action$(...)
seems to be registering itself toglobalThis
, this immediately raises several red flags for me:form
. I think a more clean and atomic interface likeserver$(...)
would be more appropriate, I don't know how many people still useform
these daysDescribe the solution you'd like
I would show my gratitude to qwik first. I'm a system architect, so instead of feature I would also constantly thinking about scaleability, security and that kind of stuff. I've done enough frontend development that these days I normally won't write more frontend code, as that would add little to my knowledge base, but more of repetitive work and reinvention of the same wheel(no offence). but qwik really caught me! in years of my frontend chore, that was something new! that I was excited, that I think can be the future of frontend development
but qwik did more, it seems it can bring resumability to the server
I've used a lot ancient tech(asp.net runat=server, jsonp, php, someother server-side function etc.
so
server$(...)
is not new, but all those ancient tech -- maybe limited by their time -- never show me the possibility to really bring resumability to the server, they all seems just syntactic sugar around XHR. qwik -- along with it's compiler -- the ability to segregate code blocks and capture, serialize scoped values -- may finally be able to do:server-side resumability
qwik currently
suspend
s in SSG andresume
s in browser, server-side resumability is like doing that in reverse. but it faces more challanges:I propose the following solution

notice a few things in the code:
scopeValue
never send to client,browserValue
is the only one coming from browser,capturedScopeValue
,scopeValue
,localValue
is captured and send to client, but not read back from client, theyresume
in serverawait
and aconfig
(if not provided,defaultConfigForYieldToBrowserAndResumeInServer
is used, if that is not provided, a default implementation is usedthe so called
config
customizes three aspect of server-side resumability, highlighted in red in the above diagramexternalizer1:(ctx,...variableInfo)
decides how variables(state) are serialized. it can, for example, detectscopedValue
is non-local(throughvariableInfo
), and write it to redis, only returning its redis key. the key, instead of data, is then send to browser, thus leaking no information(the key can be mangled and recovered only throughinternalizer1
, thus the browser gains no knowledge). it can also detect thatcapturedScopeValue
is non-local, allowing it's value to be send to the browser, optionally transform the value in the process(filter some fields etc), while also saving it to redis. the default implementation does nothing special, just leave the value in process memory. forlocalValue
, the default implementation sends the mangled identifiers to browser, on resume it uses the ones recovered from the mangled identifiers, not the browser sent one. the mangled identifiers also have internal checks to prevent identifier remangle or reuse attacksexternalizer2
adds extra routing information to the resulting url, thus when browser sends back request, LB can see its routing value and route the request to the original backend instance(or any other instance the LB deems appropriate). the default implementation adds nothing to the urlversioning
adds extra versioning information to the resulting url, thus when browser sends back request, a user-controlled(thoughconfig.versionCheck:(...)=>boolean
) verifier is run, to decide if the code is runnable on the server. the default implementation adds script build time to the url and it must match exactly with the browser send back one to continueinternalizer1
recovers variables(state) fromexternalizer1
, thus complete the server-side resumability story full-circle. it can choose to recovercapturedScopeValue
and/orscopeValue
from process memory(they may have been changed by now) or from redis. the default implementation try to recover them from process memory. it should also considerlocalValue
as if resumed in a different server process,localValue
have to be recovered too. the default implementation try to recover them first from injection made byinternalizer2
, then from process memory, minimizes the security risk, and if server resumed in different process, error. notice the different behavior for local and non-local valuesinternalizer2
can run in LB or qwik, (re)routes request based on url'sexternalizer2
route value, optionally injects data to be recovered byinternalizer1
Describe alternatives you've considered
implement server-side resumability directly, use qwik only to pass identifier references(like cookies), or entirely without qwik(use XHR or websocket directly
Additional context
No response
The text was updated successfully, but these errors were encountered: