Fork me on GitHub
#clojure-dev
<
2015-11-11
>
seancorfield00:11:13

As a data point from the other end of the spectrum, we tend to take each milestone release of Clojure to production as they are generally very stable. That lets us take advantage of new features as soon as they appear. We originally went to production on 1.3.0 Alpha 7 (or Alpha 8 ) back in 2011 and we’re on 1.8.0 Beta 1 in production right now, with Beta 2 on staging, ready to go to production in our next build.

alexmiller03:11:59

Yeah, but you're crazy :)

sveri08:11:51

The first time I read your feedback on putting 1.7.alpha something into production I was like...ok, who would do this. But after figuring your workflow out and the success you have it puts a very positive light on clojure itself. So I think it is a good advertisement for the language.

thheller15:11:36

@alexmiller: the socket REPL design page mentions some special keywords to drive some REPL behavior. was that implemented yet? can't find any references in the code?

thheller15:11:57

eg. :repl/attach

alexmiller15:11:01

It was implemented and then we decided we did not need it and it was removed

thheller15:11:11

java -cp lein classpath` -Dclojure.server.myrepl="{:address \"127.0.0.1\" :port 5555 :accept clojure.repl/repl :args [] :server-daemon false}" clojure.main -r`

thheller15:11:37

java -cp clojure-1.8.0-RC1.jar -Dclojure.server.myrepl="{:address \"127.0.0.1\" :port 5555 :accept clojure.epl :args [] :server-daemon false}" clojure.main -r

thheller15:11:45

am i missing something here?

alexmiller15:11:58

The default repl lacks support for some useful stream redirection

thheller15:11:00

oh an 'r' indeed

thheller15:11:31

i can't get this thing to run

alexmiller15:11:45

Gimme a second, otp

alexmiller15:11:01

there are some docs on this at http://clojure.org/repl_and_main btw farther down the page

alexmiller15:11:40

I would recommend that you use clojure.core.server/repl as the repl accept function - this sets up the streams for the socket appropriately which the default repl will not

alexmiller15:11:35

you are also passing a number of values you don't need to that have the same default values

thheller15:11:06

first time messing around with this stuff, just copying stuff from the design page

alexmiller15:11:37

you had a typo in the accept function above - clojure.epl, not sure if that was the source of the NPE

thheller15:11:05

clojure.core.server/repl works

alexmiller15:11:22

but might be able to improve the error reporting on a bad accept function. happy for a ticket if so.

ragge16:11:49

hi, we've stumbled upon a core.async behaviour I'm not sure is correct, would appreciate some feedback

ragge16:11:01

one example:

ragge16:11:06

(let [slow (a/chan 1 (map (fn [v] (Thread/sleep 10000) v)))
        fast (a/chan 1 (map (fn [v] v)))]
    (a/thread
      (a/>!! slow 42))
    (a/thread
      (Thread/sleep 1000)          
      (a/>!! fast 4711))
    (let [[v c] (a/alts!! [slow fast])]
      v))

ragge16:11:20

two channels, one with a "slow" xform

ragge16:11:34

put to both chans in separate threads

ragge16:11:41

then an alts!! call

ragge16:11:04

the alts!! always waits for the slow chan (even if it returns value from fast one)

ragge16:11:47

(this is [org.clojure/core.async "0.2.371"] btw)

ragge16:11:05

am I going crazy here or should the fast chan have a value available after ~1s and that should be returned by alts!! call?

alexmiller16:11:10

doing Thread/sleep will I think put that sleep in the thread of the alt take

alexmiller16:11:10

to ensure that only one of the ops succeeds there is locking that occurs over each channel involved - I suspect that coupled with the transducer may be causing what you see but I would have to look at the code and think through it

alexmiller16:11:06

if you run something like this without the transducer (instead just a go block or thread that sleeps and emits a value for example)

alexmiller16:11:56

the transducer runs under the channel lock - there is a warning somewhere that you should thus not do excessive work in your channel transformation

ragge16:11:13

thanks for having a look. we're aware that you don't want to do excessive work in a channel transformation... this was slightly accidental in our case

ragge16:11:59

seems like the definition of an operation being "ready" (in alts!) might be a little subtle when channel tranducers are involved

ragge16:11:25

the behaviour is the same even if I give the channels bigger buffers (although in this case only 1 value is ever put)

ragge16:11:41

ah, I think I see now

ragge16:11:33

the buffer add! is done under channel lock, and alt is waiting for same lock

ragge18:11:26

Otoh I thought alt only locked the handlers involved in the alt op... 😕

ragge19:11:14

i probably need to dig deep into the ReadPort/WritePort and alt impls. to understand this

ghadi19:11:47

alt handlers lock a shared flag

ragge19:11:50

@ghadi: do you also agree that a slow channel transducer would result in the alt behaviour I'm seeing?

ragge19:11:02

thanks, I'm digging through that and the channel impl

ghadi19:11:09

"yeah don't do that" simple_smile

ragge19:11:21

point taken simple_smile

ragge19:11:59

under some circumstances you might not always know the properties of the channels you're given though

ragge19:11:11

and you might want to wait at most 10s

ragge19:11:39

but yes, i see that you or the creator of the channels are misusing channel transducers then

ragge19:11:33

(by "you" I mean me)

ghadi19:11:35

general rule is that channel transducers should do no I/O or side-effects

ghadi19:11:57

data transformations 👌