This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (42)
- # aws (2)
- # babashka (69)
- # beginners (38)
- # calva (18)
- # cider (39)
- # circleci (1)
- # clj-commons (10)
- # cljs-dev (2)
- # clojure (36)
- # clojure-australia (14)
- # clojure-europe (25)
- # clojure-gamedev (40)
- # clojure-losangeles (4)
- # clojure-nl (5)
- # clojure-sweden (1)
- # clojure-uk (5)
- # clojurescript (133)
- # core-logic (24)
- # cursive (7)
- # datalevin (4)
- # datascript (3)
- # figwheel-main (1)
- # fulcro (45)
- # honeysql (1)
- # integrant (43)
- # introduce-yourself (1)
- # jobs (4)
- # leiningen (3)
- # lsp (32)
- # nextjournal (9)
- # pathom (18)
- # polylith (21)
- # portal (65)
- # re-frame (6)
- # releases (1)
- # remote-jobs (1)
- # reveal (12)
- # rewrite-clj (1)
- # sci (84)
- # tools-deps (22)
You really shouldn't cross-post unless you aren't getting an answer after a decent amount of time. Two minutes isn't very patient 🙂
It isn't a big deal. I suspect you won't get an answer until Monday "morning" US time in #integrant...
And I guess I was also thinking how I asked a slightly related question in #clojure earlier and this was my attempt at making it more specific (/another angle where I might get responses)
But yes, I will try to remember that! Actually, are there a list of rules/guidelines for clojurian slack? o:
There's a Code of Conduct, but it doesn't cover stuff like this. So we manually encourage folks not to x-post from time to time, and to be patient 🙂
What is the correct way to parse / validate untrusted data in Clojure? In the past, I thought "user data => parse as edn => spec"; but now I am concerned about algorithmic denial of service attacks.
I would use malli because it allows closed specs. And be careful what I put in those specs of course.
@U04V4KLKC: In languages with static types and serialization / deserialization generators, one can often get "size of struct + O(1)" validators; (though might still grow the stack too much, and not nearly as flexible as spec).
"Algorithmic" here as in: the attacker constructs input designed to maximize RAM / CPU usage.
(set! *warn-on-reflection* true) (def http-client-1 ;; reflection warning: reference to field build can't be resolved. (.build (doto (HttpClient/newBuilder) (.version HttpClient$Version/HTTP_1_1)))) (def http-client-2 ;; no reflection warning (let [builder (doto (HttpClient/newBuilder) (.version HttpClient$Version/HTTP_1_1))] (.build builder)))
http-client-1generates a reflection warning, but
http-client-2does not. in my mind these are equivalent, but seems not. anybody know why the latter does not generate a warning but the former does?
I don't have an answer, and these are just observations rather than a suggestions, but I found it curious that if your
http-client-1 innards are bound to a local first, it also doesn't reflect. It seems like something unusual in the behavior of
def, but that is speculative.
(def http-client-1* ;; no reflection warning (let [client (.build (doto (HttpClient/newBuilder) (.version HttpClient$Version/HTTP_1_1)))] client)) (let [client (.build (doto (HttpClient/newBuilder) (.version HttpClient$Version/HTTP_1_1)))] (.sslParameters client)) ;; no reflection warning
@(promise) will suffice here I think (if you're just looking for a blocking call) - but on second reading, I think you want an operation within the loop)
Is there a way to explicitly destroy an object in Clojure? I have a repl session where I created some huge DS in memory. In the end only the GC was running. I niled the var with all the references to the data, thinking that would take care of it. It didn't. Does this mean I still have some lingering references to the data? Is there a way to resolve an issue like this without killing the repl session?
This is what it looked like (visualvm heap size and clj-async-profiler during the end of the graph)
hm. If you're doing a traversal there's certainly a chance you're holding on to stuff you shouldn't. Are you able to share the code? If not, recreating and examining the heap is also good
I actually know where the issue is. I was more interested in why I couldn't save the the session even after I stopped the crawler.
As Joshua mentioned outside of the thread it might have been
*1 of which I did not think of at that moment
could have been a lingering object reference somewhere - there are ways to debug that with either memory dumps or live profiling tools that do "path to root" analysis. or could have been something like a gc that had not yet found the dead object or was collecting but taking a long time
on the repl if you
def ed something you can use
ns-unmap to remove it from your current ns. If you're on the repl then the last three return results and the last exception are kept around in the
*3 , and
*e vars. Once you've made sure your huge value is in none of these, you can call
(.gc (Runtime/getRuntime)) and this will hint the garbage collector to run, which may collect your value.
If after all of that the object is still around, you probably have retained a reference to it some other way.