aleph

Empperi 2019-02-28T09:40:10.000200Z

Hi! Using websocket-client to connect into websocket endpoint. This works just fine but I have a problem when target endpoint is not there when trying to make the connection

Empperi 2019-02-28T09:40:27.000600Z

The connection creation just hangs forever, no errors or anything

Empperi 2019-02-28T09:40:31.000800Z

I must be missing something

Empperi 2019-02-28T09:41:16.001400Z

I think it is because websocket-client returns a deferred which I must first dereference to use it

Empperi 2019-02-28T09:41:47.002500Z

And that dereferencing will hang until the connection is established, which it never manages to do since the target endpoint isn't available

Empperi 2019-02-28T09:42:53.004Z

So, is there a way to tell the websocket-client a connection timeout?

kachayev 2019-02-28T09:44:19.005300Z

First, you can use (d/timeout _) to fail the deferred after timeout you need

Empperi 2019-02-28T09:46:35.006100Z

OK, that was what I was more or less looking for I think

kachayev 2019-02-28T09:49:37.008900Z

Second, there’s a ConnectionTimeout that fires when you cannot establish a TCP connection. The problem with Websocket protocol is that it requires one another round-trip to setup the stream: handshake request/response (see https://github.com/ztellman/aleph/pull/422 and https://github.com/netty/netty/issues/8841). If your server is “not there”, it fails. If your server unable to finish the handshake - it’s not managed by the Aleph for now (it would be after PR is merged tho’).

Empperi 2019-02-28T09:50:29.009400Z

Right

Empperi 2019-02-28T09:50:50.009900Z

Well in this case the target server is starting sometimes when I'm trying to establish connection

Empperi 2019-02-28T09:51:04.010100Z

And it will get up eventually

Empperi 2019-02-28T09:51:14.010400Z

(or if it doesn't then there's a bigger problem)

kachayev 2019-02-28T09:53:02.012200Z

(-> (websocket-client ...)
    (d/timeout! 5e3 ::timeout)
    (d/chain' (fn [conn] (if-not (identical? ::timeout conn) conn (time/in 5e3 (websocket-client ...))))))

kachayev 2019-02-28T09:53:32.012700Z

Out of my head, didn’t test it 🙂

Empperi 2019-02-28T09:53:36.012900Z

hehe

kachayev 2019-02-28T09:54:00.013400Z

TCP doesn’t have a solution for “server is starting” as a protocol, unfortunately 😉

Empperi 2019-02-28T09:54:09.013600Z

Yeah I know

Empperi 2019-02-28T09:54:30.014Z

It is pretty obvious that I need to retry a bit later if it isn't just there

Empperi 2019-02-28T09:54:43.014200Z

And do that for x times or give up

kachayev 2019-02-28T09:55:04.014400Z

Correct

igrishaev 2019-02-28T10:55:51.017100Z

Hi! There is a lot of middleware for the HTTP client. Yet I don’t understand how to use them when sending HTTP calls. For example, when GET-ting a JSON file, how to finish with the body being parsed automatically? What option should I specify?

igrishaev 2019-02-28T10:57:21.017600Z

What I’ve tried:

@(http/get "<https://blockchain.info/latestblock>")
returns just a byte stream as body

igrishaev 2019-02-28T10:57:41.017900Z

@(http/get "<https://blockchain.info/latestblock>" 
           {:middleware middleware/wrap-request})
gives the same result

kachayev 2019-02-28T10:59:23.018900Z

Wrap-request is applied automatically

kachayev 2019-02-28T10:59:40.019400Z

:as :json should work

igrishaev 2019-02-28T11:03:00.019900Z

let me try

igrishaev 2019-02-28T11:03:50.020600Z

what works! Does it mean, I can just pass the standard clj-http args?

kachayev 2019-02-28T11:04:14.020900Z

Almost always :)

kachayev 2019-02-28T11:04:32.021600Z

There’s a list of those things that are different

kachayev 2019-02-28T11:04:45.022300Z

In README

igrishaev 2019-02-28T11:04:58.022600Z

when sending JSON body, with that work?

:form-params {:foo 42}
:content-type :json

kachayev 2019-02-28T11:09:30.022800Z

Yep

kachayev 2019-02-28T11:09:39.023100Z

Or :application/json

kachayev 2019-02-28T11:09:47.023400Z

I don’t remember exactly

igrishaev 2019-02-28T11:12:52.023800Z

yes, it seems to be the full version (defmethod coerce-form-params :application/json

kachayev 2019-02-28T11:17:10.023900Z

What about clj-http? Do they accept short version?

igrishaev 2019-02-28T11:17:29.024300Z

yes, the take just :content-type :json

kachayev 2019-02-28T11:17:53.025400Z

Feel free to open an issue with “clj-http parity” tag :)

kachayev 2019-02-28T11:18:00.025700Z

Or I’ll do that in the evening

igrishaev 2019-02-28T11:18:32.026500Z

but it’s not a problem, really. Instead, it would be nice to add more examples in readme because auto encode/decode JSON happens constantly

igrishaev 2019-02-28T11:18:54.027Z

ok probably I’ll contribute

🙏 1
igrishaev 2019-02-28T11:20:23.028Z

what is good about clj-http, you never remember all the options, but they’ve got rich base of examples, so you just copy and paste

kachayev 2019-02-28T11:21:44.028600Z

Let me know if I can help with anything

kachayev 2019-02-28T11:22:28.029800Z

The idea was that you can just copy example for clj-http and it works 😂

kachayev 2019-02-28T11:22:45.030400Z

But, yeah... documentation is a weak point for now

kachayev 2019-02-28T11:22:59.030800Z

And it requires constant attention

igrishaev 2019-02-28T11:24:11.031800Z

maybe I was confused with a docstring to aleph.http/request function which highlights only the basic args

igrishaev 2019-02-28T11:24:40.032300Z

but it’s clear now, thanks a lot!

kachayev 2019-02-28T11:25:26.032500Z

My pleasure!