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/local/client.nim | |
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/local/client.nim')
-rw-r--r-- | src/local/client.nim | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/src/local/client.nim b/src/local/client.nim index 6b605311..07f493e6 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -1,3 +1,4 @@ +import std/exitprocs import std/nativesockets import std/net import std/options @@ -11,8 +12,6 @@ import std/unicode when defined(posix): import std/posix -import std/exitprocs - import bindings/constcharp import bindings/quickjs import config/config @@ -65,9 +64,7 @@ type ibuf: string jsctx: JSContext jsrt: JSRuntime - loader: FileLoader pager {.jsget.}: Pager - selector: Selector[int] timeouts: TimeoutState pressed: tuple[col: int, row: int] @@ -78,12 +75,18 @@ type jsDestructor(Client) -func forkserver(client: Client): ForkServer {.inline.} = - client.pager.forkserver - func console(client: Client): Console {.jsfget.} = return client.consoleWrapper.console +template selector(client: Client): Selector[int] = + client.pager.selector + +template loader(client: Client): FileLoader = + client.pager.loader + +template forkserver(client: Client): ForkServer = + client.pager.forkserver + proc readChar(client: Client): char = if client.ibuf == "": try: @@ -506,25 +509,13 @@ proc acceptBuffers(client: Client) = proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize_t): cint {. importc: "setvbuf", header: "<stdio.h>", tags: [].} -proc handleRead(client: Client, fd: int) = +proc handleRead(client: Client; fd: int) = if client.pager.infile != nil and fd == client.pager.infile.getFileHandle(): client.input().then(proc() = client.handlePagerEvents() ) - elif (let i = client.pager.findConnectingBuffer(fd); i != -1): - client.selector.unregister(fd) - client.loader.unregistered.add(fd) - let (container, stream) = client.pager.connectingBuffers[i] - let response = stream.readResponse(container.request) - if response.body == nil: - client.pager.fail(container, response.getErrorMessage()) - elif (let redirect = response.getRedirect(container.request); - redirect != nil): - client.pager.redirect(container, response, redirect) - response.body.close() - else: - client.pager.connected(container, response) - client.pager.connectingBuffers.del(i) + elif (let i = client.pager.findConnectingContainer(fd); i != -1): + client.pager.handleConnectingContainer(i) elif fd == client.forkserver.estream.fd: const BufferSize = 4096 const prefix = "STDERR: " @@ -597,13 +588,8 @@ proc handleError(client: Client, fd: int) = client.loader.onError(fd) elif fd in client.loader.unregistered: discard # already unregistered... - elif (let i = client.pager.findConnectingBuffer(fd); i != -1): - # bleh - let (container, stream) = client.pager.connectingBuffers[i] - client.pager.fail(container, "loader died while loading") - client.selector.unregister(fd) - stream.close() - client.pager.connectingBuffers.del(i) + elif (let i = client.pager.findConnectingContainer(fd); i != -1): + client.pager.handleConnectingContainerError(i) else: if fd in client.fdmap: let container = client.fdmap[fd] @@ -784,8 +770,7 @@ proc launchClient*(client: Client, pages: seq[string], selector.registerHandle(fd, {Read}, 0) client.loader.unregisterFun = proc(fd: int) = selector.unregister(fd) - client.selector = selector - client.pager.launchPager(infile) + client.pager.launchPager(infile, selector) let clearFun = proc() = client.clearConsole() let showFun = proc() = @@ -888,7 +873,6 @@ proc newClient*(config: Config, forkserver: ForkServer): Client = pager.setLoader(loader) let client = Client( config: config, - loader: loader, jsrt: jsrt, jsctx: jsctx, pager: pager |