woop woop 🙂
it's more of a headache than it should be :(
@gfredericks: re our twitter conversation, what’s your solution for generators with high variance? I think maybe it’s ok, because the common case where you’re using parallel testing will be tests passing
if your tests are failing often, then generally parallelism isn’t really all that helpful anyway. Most of the time when I run test.check running overnight in #core JVMs, I do not expect to catch anything
It can slow down even in the passing case
Oh I forgot another goal
Given a seed, the result should be deterministic
So if you're preallocating work you have to give n/t trials to each thread
Yeah, I agree with that goal. That’s why I was saying that you have to partition the space and check whether all threads have passed X, where X is a failing iteration
I can see how it’ll slow down passing cases though
If one thread has lots of slow trials the others will be idle while it finished
Yeah, that’s troublesome
Especially if you have a bunch of tests to run through
So my alg has a queue of trials to run
Generally I’m just running one test overnight, on X cores
So this isn’t a problem, but I see where it’s a problem for a test suite
And the threads just pull them off the queue
I was going to say, a priority queue might be the answer
Priority?
Maybe you don’t even need to prioritise, now that I think about it
Yeah
The other problem I have is deciding how to manage the threads
I suppose I could have it just use N futures...?
You also need to ID the test cases, in case there is some variance in when the cases finish?
Maybe that's best actually
Yes they're ordered
So a lot of complexity comes from when you find the first failure but have to wait for all earlier jobs to finish first
Yep, I can see that
If you use futures, make sure to check for (Thread/interrupted) in the processing loop, so you can cancel the thread reliably after the test is done
yeah cancelling things is a big deal too
I don't know how bad it is to .stop
a thread
Yeah, it doesn’t really work well
It’s really up to the thread to behave well
if you check whether you’ve been interrupted in between test iterations, you’ll be fine with just (future-cancel fut)
C-c in nrepl calls .stop I think
future-cancel may do too, but it’s really up to the thread to behave properly
pretty sure thread.stop has been deprecated too
yep, http://stackoverflow.com/questions/16504140/thread-stop-deprecated
yeah that's the entire reason for my hesitation
it's tough in this case to ensure the thread behaves properly though since it's running user code, and so might hang
so if I don't call thread.stop, the caveat to users is "if your test or your generator hangs, you're just going to have an extra thread on your jvm until you restart it, sorry"
if user code hangs, it’s not your problem in my opinion
best you can do is exit between iterations
sure, but users have the expectation that they can C-c their tests and everything stops
what is "exit between iterations"?
I agree, but there’s nothing you can do to guarantee that. User code can always cause situations where that is not true
I mean, a thread will, at minimum, stop between an test iteration
as far as I know, there may be other situations where their code can bail safely, but there can always be other situations where things are blocked and C-c is never going to help
that's true when users are explicitly using threading constructs
when I say “may”, I mean, it depends on their code
but for user code on the main thread I think it's always true that C-c in nrepl stops it
I suppose this discussion overlaps with the "should tests run in parallel by default?" question
Ah yes, I can see how that is important
I think using futures and using an atom to aggregate the results will simplify that code a lot
so I'm glad about that;
I'm a little grumpy about how this interacts with the reporter-fn, since I think that has to be nondeterministic now
and the behavior when the reporter-fn throws an exception is potentially weirder
calling .stop on a thread is bad - it frees all monitors which can badly impact others using them
much preferred to interrupt
@alexmiller: do you think it's a problem that nrepl does it on ctrl-c?
should we be resigned to forcing repl users to restart their jvm if they execute an infinite loop?
I see ctrl-c at the builtin clojure repl just kills the whole jvm
I'm also curious if you have any sense for how realistic the monitor problem is to a user who isn't explicitly using monitors
I don’t know that there is any better solution for nrepl, but that doesn’t make it good
the thread stop thing is a real problem, which is why its deprecated. any code that uses Java locks will be affected and that includes code that is calling into the Clojure runtime in places where synchronization is used (every lazy seq uses synchronization).
that said, typically at the repl, the person typing is the one likely to be affected and they will probably just start over with (mostly) fresh resources
Java Concurrency in Practice is probably the best resource on these problems and their recommended alternatives
Yeah that's about what I thought. Seems like there's not much you can do in a general context where you don't control all the code. I'm surprised it hasn't been worth fixing (or is too hard to fix) on modern jvms