This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-27
Channels
- # announcements (4)
- # beginners (41)
- # biff (8)
- # cider (14)
- # clj-kondo (5)
- # clojure (45)
- # clojure-brasil (1)
- # clojure-europe (20)
- # clojure-nl (1)
- # clojure-norway (30)
- # clojure-uk (10)
- # clojurescript (8)
- # cursive (25)
- # datomic (20)
- # emacs (11)
- # events (1)
- # hoplon (9)
- # humbleui (7)
- # hyperfiddle (6)
- # lsp (63)
- # matrix (1)
- # observability (20)
- # off-topic (36)
- # polylith (11)
- # re-frame (2)
- # releases (1)
- # rewrite-clj (6)
- # scittle (42)
- # sql (6)
- # squint (86)
- # tools-deps (9)
Is there a way to run a clojure command in a fresh new classloader, in a way that will not affect my current classloader? I have tried this:
(defn ns-loads [ns]
(let [my-list (ArrayList.)
thread (Thread/currentThread)
old-cl (.getContextClassLoader thread)]
(.setContextClassLoader thread (RT/makeClassLoader))
(try
(let [before @(var-get #'clojure.core/*loaded-libs*)
_ (require ns)
after @(var-get #'clojure.core/*loaded-libs*)]
(run! #(.add my-list %) (reduce disj after before)))
(finally (.setContextClassLoader thread old-cl)))
(seq my-list)))
So this also loads the ns for my current classloader.You have to use the classloaders to load a separate copy of the clojure runtime, and there are all sorts of issues with that, you end up needing to serialize data passes between the clojure runtimes because of course they have different classes for all the clojure data types, etc
People keep writing tooling that does that sort of thing (polylith does it for test running) but, uh, I find it unreliable and when it breaks you get fun bugs where assoc throws an exception when you call it because it insists the PersistentMap you passed it cannot be cast to PersistentMap
I don’t mind having to serialize data
I used ArrayList for this purpose
https://github.com/polyfy/polylith/blob/master/components/common/src/polylith/clj/core/common/class_loader.clj is the polylith code
yeah this is it… I think
https://clojurians.slack.com/archives/C013B7MQHJQ/p1663100448736149?thread_ts=1663099160.123839&cid=C013B7MQHJQ is the kind of issue you can run into, and why we use a forking version of the test runner at work instead of trying to do classloader isolation
Does apply
have performance concerns?
Kind of vague I know, but I'll leave that open ended...
(Asking for a friend 🙂 )
Performance concerns are in the eye of the beholder. apply
isn't free. I've definitely seen/removed it when profiling sensitive code in the past.
I usually ask Criterium for data, e.g https://clojure-goes-fast.com/blog/benchmarking-tool-criterium/
I've checked apply
vs reduce
in Clojure and it was more performant (naive check though)... Didn't expect that.
The performance of any function in Clojure may change depending on the kind of arguments it receives and other functions it may be composed with.
apply
and reduce
do not operate in exactly the same way, although can produce similar results in many situations. Use the most appropriate function for the task and test performance if there are issues.
I have a problem, that I don’t know which channel is the right one to ask. Here is a problem, I have a handler in my webservice, that needs to open execute certain SQL statements in a transaction. We are using the next.jdbc
lib and HikariPool for connection handling.
The problem we are facing is that I want to test this handler, and I want to test it in the way that I pass in a transaction with the {:rollback-only true}
option, so everything should be rolled back. The problem here is that nested transactions are not supported. What I can do is to move code that I want to test to a separate function, test that with the {:rollback-only true}
option, and leave the transaction opening part untested with just calling that function.
Is there a better way?
I think using transaction rollbacks for cleaning up after tests is a bad idea, so the better way would be not to do that. use a fixture to set the database in a clean state before each test, or after each test (before is clearly superior, but 🤷 )
Why is it a bad idea? If the DB provides guarantees that you're happy with in the context of tests, rolling back should be much faster than setting up a whole DB.
Depends on the size of the test db, If you trust running tests using nested transactions while running in production with not nested transactions
Ah yeah, I'd certainly try to keep my tests structurally as close to the prod as possible.
FWIW, you can configure next.jdbc
to ignore attempts at nested TX in which case running a test with rollback would "work", but as hiredman
says I would not recommend that as a strategy in general.
The other thing to think about is: can you guarantee that none of your application behavior depends on multiple independent transactions? Even if you implement nested txns as savepoints like many non-clojure frameworks do, their behavior is different from multiple independent transactions.
Re: nested TX: https://cljdoc.org/d/com.github.seancorfield/next.jdbc/1.3.894/api/next.jdbc.transaction#*nested-tx*
When I did a bunch of thinking about this a while ago, the conclusion I reached was that parallelizing test execution across multiple databases and truncating everything before each test was a lot faster than any of the non-txn-rollback alternatives, and the txn-rollback approach was undesirable for the previously-stated reasons. It would be really nice if we had first-class support for this sort of thing from databases, or if clearing/creating data didn’t take so long
Thank you for the tips! I’ll see how this works for us. Either way, the integration tests will use a fully prepared DB anyways with a setup closer to the production setup.
Anyone have a decent Java balanced paren regex handy? I can pull something from SO but thought I'd ask here for something tried and true...
Java is not a regular language, you can't use RegEx to properly parse it. Even just parentheses. (Assuming I understood you correctly.)
I want a java compat regex to match a substring of balanced parens in a string
https://stackoverflow.com/questions/546433/regular-expression-to-match-balanced-parentheses
I'll just grab something there, but if someone here has used one they like, please speak up 🙂
as the second answer there points out, nested balanced parenthesis don't form a regular language (recognizable with a state machine), I think balance nested stuff requires maybe a push down automata
was just asking for a regex here, friends 🙂
there are extensions here and there to regexes that allow for things like recursion (the .net impl on that page), but the java built in regex library (which is what clojure uses) doesn't have that
so the java answer on that page is prefixed with a disclaimer that it only works to a fixed amount of nesting
I'm aware
@U0NCTKEV8 This one claims there's no limit but I haven't spent any time trying to understand why or what its other limitations are: https://stackoverflow.com/a/47162099/564509
Also, @U05H8N9V0HZ if there any, tiniest chance of not using any sort of regular or "regular" expressions to achieve what you want, the best approach would probably be using that alternative. Whatever you find might work in your tests, until it doesn't in real life.
Just need something to make a deadline here.
fwiw I can tokenize all of clojure/core.clj with a single readable regex and a single application (of that regex to the library text string).
but certainly there are limits, I know...
In case you haven't seen it and have a minute so spare. :) https://stackoverflow.com/a/1732454/564509 Matching parentheses with RegEx is exactly the same task, with exactly the same issues.
no minutes left 😄