diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-12 22:53:49 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-12 23:04:47 +0100 |
commit | 64e6debefbc2ab00735b83ae1def168775006844 (patch) | |
tree | 0262e1b875c05ca453885bde0b24281047f87e4d /src/loader | |
parent | 2a8f0e7061babf03bc614554e3d5fd32220c305c (diff) | |
download | chawan-64e6debefbc2ab00735b83ae1def168775006844.tar.gz |
client: fix blocking reads on container connection
Sometimes, headers take a while to reach us even after the result has been sent. e.g. echo 'Cha-Control: Connected' sleep 5 echo 'Cha-Control: ControlDone' ^ this froze the UI for 5 seconds, that's certainly not what we want. Since we don't have a proper buffered reader yet, and I don't want to write another disgusting hack like BufStream, we just use a state machine to figure out how much we can read. Sounds bad, but in practice it works just fine since loader's response patterns are very simple.
Diffstat (limited to 'src/loader')
-rw-r--r-- | src/loader/loader.nim | 42 | ||||
-rw-r--r-- | src/loader/response.nim | 6 |
2 files changed, 19 insertions, 29 deletions
diff --git a/src/loader/loader.nim b/src/loader/loader.nim index 904069a6..c4b497ac 100644 --- a/src/loader/loader.nim +++ b/src/loader/loader.nim @@ -785,12 +785,18 @@ proc connect(loader: FileLoader; buffered = true): SocketStream = return stream return nil -#TODO: add init -proc fetch*(loader: FileLoader; input: Request): FetchPromise = +# Start a request. This should not block (not for a significant amount of time +# anyway). +proc startRequest*(loader: FileLoader; request: Request): SocketStream = let stream = loader.connect(buffered = false) stream.swrite(lcLoad) - stream.swrite(input) + stream.swrite(request) stream.flush() + return stream + +#TODO: add init +proc fetch*(loader: FileLoader; input: Request): FetchPromise = + let stream = loader.startRequest(input) let fd = int(stream.fd) loader.registerFun(fd) let promise = FetchPromise() @@ -866,8 +872,6 @@ proc handleHeaders(response: Response; request: Request; stream: SocketStream) = stream.sread(response.outputId) stream.sread(response.status) stream.sread(response.headers) - # Only a stream of the response body may arrive after this point. - response.body = stream proc onConnected*(loader: FileLoader, fd: int) = let connectData = loader.connecting[fd] @@ -879,6 +883,8 @@ proc onConnected*(loader: FileLoader, fd: int) = let response = newResponse(res, request, stream) if res == 0: response.handleHeaders(request, stream) + # Only a stream of the response body may arrive after this point. + response.body = stream assert loader.unregisterFun != nil let realCloseImpl = stream.closeImpl stream.closeImpl = nil @@ -938,31 +944,21 @@ proc onError*(loader: FileLoader; fd: int) = buffer[].buf = "" response.unregisterFun() -# Start a request. This should not block (for a significant amount of time -# anyway). -proc startRequest*(loader: FileLoader; request: Request): SocketStream = - let stream = loader.connect(buffered = false) - stream.swrite(lcLoad) - stream.swrite(request) - stream.flush() - return stream - -# Read a response from a request stream (received from startRequest). This -# blocks until headers are received. -proc readResponse*(stream: SocketStream; request: Request): Response = +# Note: this blocks until headers are received. +proc doRequest*(loader: FileLoader; request: Request): Response = + let stream = loader.startRequest(request) let response = Response(url: request.url) stream.sread(response.res) if response.res == 0: response.handleHeaders(request, stream) + # Only a stream of the response body may arrive after this point. + response.body = stream else: - stream.sread(response.internalMessage) + var msg: string + stream.sread(msg) + stream.close() return response -# Note: this blocks until headers are received; see above. -proc doRequest*(loader: FileLoader; request: Request): Response = - let stream = loader.startRequest(request) - return stream.readResponse(request) - proc shareCachedItem*(loader: FileLoader; id, targetPid: int) = let stream = loader.connect() if stream != nil: diff --git a/src/loader/response.nim b/src/loader/response.nim index f419c432..6b4ec64e 100644 --- a/src/loader/response.nim +++ b/src/loader/response.nim @@ -7,7 +7,6 @@ import io/promise import io/socketstream import js/error import js/javascript -import loader/connecterror import loader/headers import loader/request import types/blob @@ -154,10 +153,5 @@ proc json(ctx: JSContext, this: Response): Promise[JSResult[JSValue]] return ok(JS_ParseJSON(ctx, cstring(s), cast[csize_t](s.len), cstring"<input>"))) -func getErrorMessage*(this: Response): string = - if this.internalMessage != "": - return this.internalMessage - getLoaderErrorMessage(this.res) - proc addResponseModule*(ctx: JSContext) = ctx.registerType(Response) |