Fork me on GitHub
#core-async
<
2022-01-31
>
Drew Verlee17:01:18

I'm cross posting this question from #macchiato because i'm guessing it might be a core async misunerstanding i have more then something related to the node http server handler interaction Why would a macchiato server handler that consumes a promise inside a go block like this

(fn [request respond] (go (respond  (<p! (some-core-aysnc-channel request)))))
result in an error about the stream write happening after end? I'm unsure what respond is doing, noly that it should be passed a hashmap with the response schema (body, status, etc...). I assume <p! is asynchoronous so it will block tell it gets the result. I'm not manully calling node server "end" or "write" here. full stack trace is from my project and not the example code above, but the idea should be the same:
Error [ERR_STREAM_WRITE_AFTER_END] [ERR_STREAM_WRITE_AFTER_END]: write after end
    at new NodeError (node:internal/errors:329:5)
    at write_ (node:_http_outgoing:751:11)
    at ServerResponse.write (node:_http_outgoing:710:15)
    at /home/drewverlee/archmedx/kyber/server/dev/out/cljs-runtime/macchiato/http.cljs:110:5
    at /home/drewverlee/archmedx/kyber/server/dev/out/cljs-runtime/macchiato/http.cljs:106:10
    at respond_SINGLEQUOTE_ (/home/drewverlee/archmedx/kyber/server/dev/out/cljs-runtime/reitit/ring.cljc:119:43)
    at respond__$1 (/home/drewverlee/archmedx/kyber/server/dev/out/cljs-runtime/macchiato/middleware/restful_format.cljs:110:24)
    at switch__45133__auto__ (<eval>:75:27)
    at <eval>:212:29
    at Function.server$core$state_machine__45134__auto____1 [as cljs$core$IFn$_invoke$arity$1] (<eval>:234:4)
Note the go block correctly returns the results if run outside the handler context.

noisesmith17:01:34

if I'm reading correctly, most web servers assume that when your handler returns, that means it can write and close the response stream

noisesmith17:01:12

unless you eg. return a channel or stream (which it would then use to fulfill the request)

Drew Verlee19:01:52

so i need to get the result from the channel and .then call the handler? that doesn't make any sense when i say it out loud, so i'm guessing no.

hiredman22:01:45

https://github.com/macchiato-framework/macchiato-core/blob/master/src/macchiato/http.cljs#L47-L97 couldn't leave it be, looks like this protocol function is called, and will raise an error if you don't return a type that satisfies the protocol

hiredman22:01:21

not return, if you don't pass a type that satisifies the protocol to respond

hiredman22:01:33

and it least there there is no impl for promises

Drew Verlee22:01:09

Thanks. Yea, i was worried that was likely the case. I was trying to understand if i could get around that somehow. If i deliver the promise in the handler shouldn't it have to block tell it resolves and becomes a value? ill figure it out, might have to build up my understanding a bit though. I was hoping to just be able to toss things in.

hiredman22:01:05

the docs for that project use handlers that take callbacks and never actually discuss what those callbacks mean and how to use them, good luck