Fork me on GitHub
#duct
<
2018-11-19
>
rickmoynihan10:11:59

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?

rickmoynihan11:11:29

Running module.ataraxy 0.3.0-alpha3

rickmoynihan11:11:18

unstrumenting and reseting again causes things to work again

scottlowe19:11:18

@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.

rickmoynihan22:11:36

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 instrumented definition of the coercer… so the end result of the fix is the same as not instrumenting at all.

rickmoynihan22:11:10

I wonder if manually halting initing might work better after instrumenting, to avoid the refresh altogether…

rickmoynihan22:11:35

Nope, that causes the same problem

rickmoynihan22:11:11

I wonder if the eval in ataraxy compile is the problem; eval is a bit fishy

scottlowe22:11:59

@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.

rickmoynihan22:11:52

hmmm ok, cos that’s what I’ve tried and its not working… but the steps are a little fiddly

scottlowe22:11:59

Perhaps I just got lucky with compilation, and it’s not deterministic :thinking_face:

rickmoynihan22:11:25

lol - lets hope it’s deterministic

rickmoynihan22:11:14

regardless I still don’t quite understand why it errors like this

scottlowe22:11:51

The constructor error itself?

weavejester22:11:13

If you find anything that needs fixing in Ataraxy, report it as an issue on the Github repo.

rickmoynihan22:11:20

yeah - I understand it’s probably stale

rickmoynihan22:11:11

Cheers @weavejester… I’ll certainly file an issue

rickmoynihan22:11:32

just trying to understand the cause

weavejester23:11:10

It might be that the coercers are loaded by symbol, without a corresponding :require in the ns declaration.

weavejester23:11:28

tools.namespace relies on statically reading the ns declaration to work out the dependencies.

rickmoynihan23:11:15

interesting… the coercers are just defined in the system config map… so yeah no :require

weavejester23:11:11

Though I'm not sure why the system reset wouldn't solve that, since the routes should be recompiled every time.

rickmoynihan23:11:35

@weavejester: would it be possible to avoid that eval?

weavejester23:11:48

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.

weavejester23:11:57

I'd look into it more, but I need to get to bed 🙂

👍 4
scottlowe23:11:14

@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.

rickmoynihan23:11:21

Ok I think the work around is simple, just (st/instrument) after the (reset); that works as expected

😌 4