Fork me on GitHub
#clojurescript
<
2016-05-13
>
risto01:05:46

Is there any way to have core.async fetch things in paralell but still maintain the given order?

risto01:05:37

I looked at pmap but it looks like it got removed at some point

pat04:05:38

@risto js is single threaded... No // threads, no pmap.

pat04:05:03

You can synchronize things by keeping a vector of recieving chans and park/process them in order

jr04:05:18

@risto:

(go [(<! source-1) (<! source2) (<! source3)])

danbunea08:05:09

Hi, I have a problem with html encoding this text: encoded <script>alert(1);<script> is rendered fine by react https://jsfiddle.net/pufhzme5/ but not by reagent http://cljsfiddle.com/#gist=1d66d8b98e0d0f5c09b7c1d8eec5d97e

joost-diepenmaat09:05:02

@danbunea: that’s because JSX processor modifies the code

joost-diepenmaat09:05:07

the string literal

joost-diepenmaat09:05:16

var n = "encoded <script>alert(1);<script>" ReactDOM.render( <Hello name={n} />, document.getElementById('container')

joost-diepenmaat09:05:29

does not unescape, for example

joost-diepenmaat09:05:16

in reagent it’s perfectly safe to do [:h1 "<script>alert(1);<script>”]

danbunea09:05:03

@jooeltavares: I load the escaped values from the database. They;re put there by someone else. So I want to see <script>alert(1);<script> on the screen, but somehow I still see <script>alert(1);<script>

joost-diepenmaat09:05:35

then you should decode the html yourself, first.

joost-diepenmaat09:05:19

it would be the same in plain react with JSX (see snippet above) - since the > conversion only happens in JSX literals

joost-diepenmaat09:05:15

clojure.string/replace should work fine assuming the only things that are escaped are < and >

joost-diepenmaat09:05:25

and &, obviously 🙂

joost-diepenmaat09:05:46

in general, it’s a bad idea to put escaped values in your data store.

joost-diepenmaat09:05:05

(-> input (string/replace #”&gt;” “>”) (string/replace #”&lt;” “<”) (string/replace #”&amp;” “&”))

danbunea09:05:42

yes, I was hoping to avoid decoding myself all the values. And for the server, there's nothing I can do...

joost-diepenmaat09:05:26

you might work with [:div {:dangerouslySetInnerHTML {:__html "<b>I am bold</b>"}}]

joost-diepenmaat09:05:56

but as the name implies that’s dangerous

joost-diepenmaat09:05:29

the question then becomes: how much do you trust that the encoded string is “correctly” encoded ?

danbunea10:05:51

dangerouslySetInnerHTML has a lot of downsides, mainly in the lifecycle of a component, so I'd avoid it

risto11:05:41

@pat @jr Am I missing something? I'm not just trying to synchronize things, I want them to be fetched in parallel but retain their order, like [this](https://github.com/caolan/async#paralleltasks-callback)

risto11:05:11

So the snippet I just posted definitely waits for the first request to finish before going to the second, and so on. So it's definitely not parallel.

risto11:05:39

If I do (<! levels) and bring up the Dev Tools Network panel, it clearly shows this

risto11:05:51

Or am I not understanding something about core.async?

risto11:05:09

The third request fetches it from the remote server, so it's substantially slower. But request 4 waits for the lag before even starting

darwin11:05:18

@risto: I can confirm that @jr’s code snippet does not run in parallel

darwin11:05:27

I think you just want to create those channels, wait for them all to close, then process the results

fasiha11:05:32

@risto <! definitely blocks, so that's not surprising. Edit: hmm, re-reading the docs, it "parks" if nothing is available.

fasiha11:05:49

take! will return immediately but you have to give it a callback to execute

fasiha12:05:07

Create a single channel for your responses, have have your GET function put the result of each web request on that channel. Then use a go-loop to chew thru the responses as they come in.

pataprogramming12:05:08

Anyone used the sente component in system? I'm trying to figure out how the sente-routes are meant to be wired into the compojure handler.

risto13:05:50

@darwin: Thanks, your solution worked

taylor.sando15:05:44

I'm assuming this is not possible because of Javascript's single threaded nature, but is there a way to pause a function and return to it later, without the function being called needing to setup a setTimeout, or polling the time and scheduling itself later?

darwin15:05:53

@taylor.sando: it is not possible, but it can be emulated, via core.async library, this library auto-magically rewrites your seemingly linear code into “setTimeouts” with callbacks

taylor.sando15:05:53

Can it return to the function after the timeout though? I know you can set a function for execution with a timeout, but will it return to where it was before?

darwin15:05:17

you can write code which looks linear, keeps its context and lives in the same function, so I would answer “yes"

taylor.sando15:05:07

For example, running a datascript query that you don't want to hog the cpu that might get ran every X milliseconds until it is complete

darwin15:05:34

yes, that can be done

pat16:05:38

@taylor.sando: if in browser, that sounds like a great webworker candidate

taylor.sando16:05:32

I'm just wondering what the limits are of serializing a large datascript database each time, or copying it to something like indexedDB, which I believe can be accessed by any web worker

pat16:05:53

@risto you can doseq <! Channels and it will park on each in order... Useful in alot of places

risto16:05:39

@pat That won't fetch the channels in parallel, that's what I was originally doing. @fasiha rightfully mentioned that <! will block, and take! isn't useful in this case bc it needs a callback. @darwin found a solution though ^^

pat16:05:23

Sure but there is no parallel here and no blocking. Core async is a loop

pat16:05:24

You can make multiple request in order and then process them in order, but all parallelism is an illusion

risto16:05:38

The solution @darwin gave is definitely parallel, and sorts it in the order that it was executed

darwin16:05:21

@pat: core.async is not a loop, and parallelism is doable with callbacks, core.async rewrites your linear code to callbacks and properly handles context saving/restoration using a state machine

darwin16:05:34

that kind of code which is hard to write by hand

pat16:05:54

It is, every goog.async.nextTick

darwin16:05:14

right, and nextTick is fancy setTimeout, so not a loop

pat16:05:23

Parallel means multiple threads, this is not possible

pat16:05:45

It loops through callbacks, thats how the browser runtime works

pat16:05:56

This is all sequential

risto16:05:36

You're just arguing semantics though. Non-blocking I guess would be a more accurate term.

darwin16:05:38

you are right, but selected API functions can run in parallel behind the scenes, but you have to use callbacks with them

pat16:05:06

@risto semantics matter :-)

risto16:05:20

In Javascript there's no confusion, since it's single-threaded

risto16:05:35

Unless you're talking about webworkers

pat16:05:41

Ok, but lots of people do not understand that

pat16:05:49

It comes up alot here

risto16:05:57

Well, in any case, @darwin found a non-blocking solution, so in a sequence of requests each request doesn't have to wait for the previous one to finish

risto16:05:15

Basically like async.parallel from the popular npm async library

pat16:05:36

You asked about pmap is all. Glad you found a solution

risto16:05:24

Yeah it was 6am last night when I dug that up lol

risto16:05:07

Didn't make the connection between pmap and pthread

fenton16:05:00

@dnolen: FYI bruce hauman had a switch: ':websocket-host' which allows the browser to work with figwheel when the browser is not local. So now can REPL around any device that connects into the server! Yay Bruce!

devth16:05:44

has anyone seen

NoSuchMethodError: com.google.common.base.CharMatcher.javaUpperCase()Lcom/google/common/base/CharMatcher
when using :optimizations in cljsbuild? happens for any setting except :none

devth16:05:56

lein-cljsbuild 1.1.3

devth16:05:28

so this happens in clojurescript 1.8.51 but not 1.8.40

devth16:05:57

must be related to > bump Closure Compiler to v20160315

manutter5116:05:27

mitchelkuijpers was having that error on May 11th in the #C06DT2YSY channel, said it might have been related to having the wrong/outdated version of guava somewhere?

devth17:05:25

my only guava dep 18.0 is being pulled in by datomic-free

manutter5117:05:59

I pasted com.google.common.base.CharMatcher.javaUpperCase()Lcom/google/common/base/CharMatcher string in the search box in slack and that came up with a “jump” link if you’d like to review the conversation — I don’t know anything about it except I recognized that weird message

mitchelkuijpers17:05:11

Yes you need to have guava 19 if i recall correctly. It has todo with the newest clojurescript

devth17:05:18

ok thanks.

devth17:05:25

why isn't clojurescript pulling it in itself?

mitchelkuijpers17:05:43

Maybe you have a conflict

mitchelkuijpers17:05:58

And 18.0 probably wins

mitchelkuijpers17:05:09

It is pulling it in

devth17:05:55

ok you're right. (i was looking at deps with 1.8.40). excluding guava from datomic dep appears to work (hopefully datomic still works!).

mitchelkuijpers17:05:24

It does for us 👍

devth17:05:32

great. thanks!

danielsz17:05:25

@pataprogramming: Did you sort it out? In system we have a Sente component where the compojure routes are already configured, so you don't have to. You just plug in them when composing the System map.

pataprogramming17:05:50

@danielsz: That was the bit I have been trying to figure out. I've got system.components.sente added to the system map, and I've seen that sente-routes is in there. This is probably pretty basic, but I then can't figure out how they should be composed with the other compojure handlers.

pataprogramming17:05:30

Just adding the component doesn't seem to activate the /chsk endpoints.

pataprogramming17:05:36

It seems like there should be a dependency declared, but that's not in the usage examples.

danielsz17:05:43

@pataprogramming: Yes, the wiring is always the hardest part 🙂 I think I have an example to show you, let me check.

pataprogramming17:05:50

Oh , awesome. Thanks!

pataprogramming18:05:25

@danielsz: Super useful! Thanks! I'll dive back in later today.

dnolen18:05:48

@fenton: glad it worked out!

fenton18:05:16

just got cider connect working too....so am in heavenly bliss for cljs development on mobile devices... if anyone wants tips for that let me know...

pataprogramming19:05:36

@danielsz: That looks like exactly what I need to get unstuck. Thanks! I'll let you know how it goes.

devth23:05:49

when you turn on :optimizations and the resulting file is nearly empty – that indicates cljsbuild/google closure doesn't know enough about your code and it's optimizing it all away?

bensu23:05:26

@devth: it might mean that it didn’t get an entry point so there is nothing to compile

devth23:05:44

bensu: it's compiling tons of stuff when i don't use optimizations

bensu23:05:37

if you have a main function but never call it top level, :optimizaions :advanced will compile nothing

bensu23:05:31

but :none will compile all your files regardless

bensu23:05:57

that may explain what you see.

devth23:05:31

main is just a namespace right?

devth23:05:04

the namespace that my main refers to initializes the app