I have an issue where if I turn (clojure.spec.test.alpha/instrument)
on to instrument my specs; I get an exception when running (reset)
. Any idea what that might be?
Running module.ataraxy 0.3.0-alpha3
unstrumenting and reseting again causes things to work again
@rickmoynihan If you are instrumenting an Ataraxy coercer, then try executing (clojure.tools.namespace.repl/refresh-all)
after (clojure.spec.test.alpha/instrument)
and before your (reset)
.
Ataraxy compiles routes and coercers here: https://github.com/weavejester/ataraxy/blob/master/src/ataraxy/core.clj#L255-L261
When instrument is turned on, a dynamic spec-checking-fn
wrapper function (a.k.a “checked”) is swapped in for the raw coercer function by instrument here:
https://github.com/clojure/spec.alpha/blob/master/src/main/clojure/clojure/spec/test/alpha.clj#L171-L177
More specifically, the clojure.spec.test.alpha$spec_checking_fn$fn__3026
mentioned on line 187
in your stacktrace. reset
only reloads namespaces that it knows has changed, but it doesn’t know about this “new” coercer function, so it’s best to reload all namespaces with refresh-all
, so that Ataraxy can compile the new definition.
Certainly, (regardless of the exact mechanism in play) I managed to reproduce your error with instrument
and reset
and a custom instrumented coercer; and the issue went away after executing refresh-all
.
Yes, I think you’re right @scottlowe, that the problem is with compile. However I don’t think your solution actually works; as whilst it stops the exception, the refresh-all
clobbers the instrument
ed definition of the coercer… so the end result of the fix is the same as not instrumenting at all.
I wonder if manually halt
ing init
ing might work better after instrumenting, to avoid the refresh
altogether…
Nope, that causes the same problem
I wonder if the eval
in ataraxy compile
is the problem; eval
is a bit fishy
@rickmoynihan I did have instrument working after a refresh-all and a reset. However, I may have reported the sequence of commands incorrectly. Perhaps you need to execute instrument twice (?). Haven’t got it in front of me now, but I did have some luck with this (no compile error after a reset) and then I deliberately sent data that would fail the instrumented coercer spec, and it did.
hmmm ok, cos that’s what I’ve tried and its not working… but the steps are a little fiddly
Perhaps I just got lucky with compilation, and it’s not deterministic :thinking_face:
lol - lets hope it’s deterministic
regardless I still don’t quite understand why it errors like this
The constructor error itself?
If you find anything that needs fixing in Ataraxy, report it as an issue on the Github repo.
yeah - I understand it’s probably stale
Cheers @weavejester… I’ll certainly file an issue
just trying to understand the cause
It might be that the coercers are loaded by symbol, without a corresponding :require
in the ns
declaration.
tools.namespace relies on statically reading the ns
declaration to work out the dependencies.
interesting… the coercers are just defined in the system config map… so yeah no :require
Though I'm not sure why the system reset wouldn't solve that, since the routes should be recompiled every time.
@weavejester: would it be possible to avoid that eval
?
I'm not sure how it would be. Ataraxy compiles its routes into code before running. Since that happens after compilation time if it's loaded from an Integrant config, it needs an eval
.
I'd look into it more, but I need to get to bed 🙂
@rickmoynihan I looked at this error under the debugger and Reflector/invokeConstructor
was looking for a 4 arg constructor for the instrumented function class that Ataraxy had in its coercers map, rather than the original coercer function class which had a different ctor arity, so something is out of step in terms of compilation.
Ok I think the work around is simple, just (st/instrument)
after the (reset)
; that works as expected