Fork me on GitHub
#beginners
<
2016-02-02
>
gabehollombe02:02:44

I'm using a library that exposes a websocket connection to me as a manifold/stream. I can connect this to a core.async channel with manifold/stream.->source without a problem. However, if the websocket closes its connection, I'd like to reconnect the stream to my async channel. Manifold provides manifold/on-closed which I can use to register a callback to execute when the stream closes, but I'm having trouble figuring out how to set things up so that anytime my manifold/stream closes, I can get a new one connected back to my core.async channel. Can anyone help point me in the right direction?

jonahbenton02:02:22

hey @gabehollombe sounds like the callback will need to be a closure, closing over the core.async channel you want to reconnect to. and it will need to be able to retrieve a new websocket connection. if you can share some code folks can probably help more.

gabehollombe03:02:58

Yeah, let me try and get a simple example together in a gist.

gabehollombe03:02:05

Here’s an example re-stating my question in clj form as a gist: https://gist.github.com/gabehollombe/b195e5c725784ee1bb54

gabehollombe03:02:19

@jonahbenton: I understand creating closures. My problem is that my brain doesn’t understand how to create a disconnect-handler function that can reference itself again when the new stream closes. I hope this makes sense

gabehollombe08:02:18

Thanks a ton, @jonahbenton — I’ll give this a shot tonight

gabehollombe08:02:25

it makes perfect sense to me, too

andrew-clj10:02:27

Thank you @jonahbenton for that implementation using a lazy sequence.

gabehollombe10:02:16

@jonahbenton: Here’s a slight re-gist using an atom so I can poke at the reconnected socket after it gets re-created. Look OK to you? https://gist.github.com/gabehollombe/1850cd9bc985d7dcb313

jonahbenton15:02:51

hey @gabehollombe: hmm, does that gist work? the use of disconnect-handler in the on-close should fail, no?

krchia16:02:23

hi, in a compojure response, if the return value is a html string

krchia16:02:46

it will be transformed into a proper response with :status, :header keywords etc right?

krchia16:02:51

i’ve tried to “graduate” from just handling the html string and letting the macro work its dark magic but what i get instead is a downloaded file with the html when i try to visit the route

jeff.engebretsen16:02:32

I know almost nothing about compojure but the sample app I did has the HTML wraped in (html5 ...) from hiccup.page and it renders fine.

jeff.engebretsen16:02:18

Sorry, it's not an HTML string. It's a hiccup list of stuff.

krchia16:02:29

hmm, i have no problem with just using the html generated from the enlive deftemplate

krchia16:02:40

just want to store a session

chadhs20:02:16

so here’s a fun question, is there an easy way to pass in and use command args in a clojure app?

chadhs20:02:28

like java -cp my-app.jar product-id=“1234”

jeff.engebretsen20:02:58

Mostly I see people pass in a map string "{:product-id 12345}"

jeff.engebretsen20:02:18

Then you can turn that into a clojure map in your -main function.

chadhs20:02:37

so pass in my args as a map, that makes sense

chadhs20:02:57

@jeff.engebretsen: another newbie Q related to that

chadhs20:02:12

if i want to write some small functions that will be called within -main

chadhs20:02:29

they would have access to those args when run within main, yes?

jeff.engebretsen20:02:11

No, you'd have to pass the argument map into them.

chadhs20:02:54

ah, so the crux of my overall Q is how do i ship that map to my other functions

chadhs20:02:01

(defn blah1

chadhs20:02:11

then finally (defn -main

jeff.engebretsen20:02:18

you can set the map in some global atom.

seriousbug20:02:33

Why not just pass it as an argument?

jeff.engebretsen20:02:37

or just a def but that would be less idiomatic.

chadhs20:02:02

essentially i don’t know how to do that.

chadhs20:02:13

how do i capture an arg i pass on the cli

chadhs20:02:50

java -cp my-app.jar “{:product-id 1234 :event-ids [1 34 67 89]}”

chadhs20:02:10

how can i do something with that map

chadhs20:02:56

(ps i truly appreciate the help)

polymeris20:02:26

you could also pass your arguments as java properties: -Dproduct.id=1234, then get them with environ (env :product-id)

jeff.engebretsen20:02:09

Here's an example using atoms. You could put the whole thing into an atom or break out the arguments. https://clojuredocs.org/clojure.core/atom#example-542692cec026201cdc326db7

jeff.engebretsen20:02:03

If the arguments are defined already (def product-id 0) you can use binding (binding [product-id (:product-id arg-map)] (fn-that-uses-product-id))

jeff.engebretsen20:02:02

That'll shadow the global var until you exit the binding form.

chadhs20:02:13

maybe my question is even easier than it seems, i just don’t know how to refer to those commandline args

chadhs20:02:19

do i just “have access to them"

chadhs20:02:26

hmm , not sure how to word my Q

jeff.engebretsen20:02:05

Are you talking about in your -main fn?

chadhs20:02:20

@jeff.engebretsen: i believe so, but it would be nice not just have one giant main function

chadhs20:02:44

like pass a map as a cli arg then do a bunch of stuff with that data and have it called from main or something

chadhs21:02:43

im basically wanting to use clojure in place of shell script where a shell script is a bit of a pain. shell scripting argument handling is a cinch but for the problem i’m solving i’d love to do the work with clojure

solicode21:02:44

From your main function, you have access to the args. So you can grab what you need from the args and then call other functions using them.

chadhs21:02:25

@solicode: so i can call other functions i define within main and pass args to them since they’d have access within main

chadhs21:02:33

is that correct?

solicode21:02:35

(defn -main [& args]
  (let [[first-arg second-arg] args]
    (my-function first-arg second-arg)))

solicode21:02:56

Well, the functions wouldn’t be defined in main

chadhs21:02:56

but i’d need to define those functions all within main?

solicode21:02:00

you just call it from there

chadhs21:02:10

that feels much cleaner

solicode21:02:40

You can define the functions elsewhere, like a different namespace even and call them from -main

chadhs21:02:00

@solicode: rock on thanks, going to work on this now.

chadhs21:02:17

it’s an excuse to try a teeny bit of clojure at work

chadhs21:02:05

@solicode: this is a cheesy simple example but it works

chadhs21:02:11

thnx again all

chadhs21:02:37

if you pass in a command line arg it show up as a string, is there a way to “deserialize” that

chadhs22:02:07

like just strip the quotes? want to buy (no-longer-a-string) fn haha

solicode22:02:16

You can use read-string, but I would use the edn version: https://clojuredocs.org/clojure.edn/read-string

chadhs22:02:49

@solicode: you’re a lifesaver thanks. was chasing my tail on clojuredocs

chadhs22:02:49

@solicode: boom!

lein run "{:product-id 76046 :event-pairs [[1 23] [34 567] [2 87]]}"
Producut ID: 76046 Event Pairs: [[1 23] [34 567] [2 87]]

solicode22:02:26

Glad it’s working simple_smile

chadhs22:02:40

now i can go do the “real” work thank you.