This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-07-25
Channels
- # announcements (9)
- # babashka (38)
- # beginners (41)
- # biff (1)
- # clojure (19)
- # clojure-europe (7)
- # clojure-uk (2)
- # clojurescript (3)
- # code-reviews (30)
- # conjure (4)
- # cursive (8)
- # datomic (32)
- # docker (2)
- # emacs (7)
- # etaoin (2)
- # fulcro (37)
- # graphql (2)
- # jobs (1)
- # jobs-discuss (8)
- # leiningen (10)
- # lsp (36)
- # meander (4)
- # missionary (4)
- # nbb (12)
- # off-topic (1)
- # other-languages (10)
- # pathom (11)
- # re-frame (5)
- # reitit (4)
- # remote-jobs (3)
- # shadow-cljs (13)
- # sql (1)
- # tools-build (4)
- # tools-deps (31)
- # xtdb (2)
What is the difference between lein install
and lein deps
?
Am asking to find out which one should I run in my CI/CD test pipeline before running lein test
This is my CI/CD pipeline for test,
test:
stage: test
image:
name: clojure:lein-2.9.8-alpine
script:
- lein install
- lein test
lein deps
download and examine dependencies
lein install
is for installing jar and pom files generated from your project into local maven repository.
As a side effect lein install
will download dependencies as well as lein deps
but it also does unnecessary (at least for CI/CD) jobs.
btw. lein help %command%
will give you better explanation
also in most cases you don’t need any command before running lein test
thanks a lot @U04V4KLKC 🙂
one place you can use lein deps
is to download the dependencies and let the CI cache them. Next time if the dependencies don't change the downloads wont happen again. But I'd also do this if and when the download takes longer. Often its a premature optimisation 🙂
I was thinking of a way to cache dependencies, since lein test runs on every push to remote and dependencies are not changing that often. Will try lein test after lein deps and see if it reduce the time it takes to run tests. Thank you for the tip @U7ERLH6JX
so the general flow would be • expand cache • lein deps • cache ~/.m2 path using the hash of project.clj as the key • other lein commands ...
how to type hint rest arguments? (defn foo [& ^bytes byte-arrays] ...
- is that correct?
update: okay, [^bytes & byte-arrays]
seems to work. nevermind :)
that doesn’t work. [^bytes & byte-array]
will add typehint for symbol &
and will have no affect later in the code.
(set! *warn-on-reflection* true)
(defn foo [^bytes & bs]
(String. bs))
this snippet will give you a reflection warning
(defn foo [& bs]
(let [^bytes bs bs]
(String. bs)))
so to make it right you can add a let expression (as in the snippet above ^ ) with proper type hintSometimes my JVM seems to be working very hard and I'm not doing anything in particular - haven't executed anything in the REPL recently and didn't start any long-running tasks. Is there some way to see what it's up to, or is a simple JVM restart the best approach if it only happens on rare occasion?
you can attach something like https://visualvm.github.io/ (which depending on the version you are using may be bundled with the jvm). It'll let you monitor the gc process (the usual suspect) and which threads are running. If you plan on running the application in production, it may be useful to learn how to debug these sorts of things, but if it's just an intermittent problem on your machine, restarting the jvm is often way easier 😉
@U01AKQSDJUX thanks, I've seen that around but haven't tried it yet. Got it up and running now. Looks like a good tool to get familiar with.
You often have to pass some options to the jvm when you start it to allow visual vm to attach to it and collect data. You can also send it signals to get it to spit out a thread dump (basically a bunch of stack traces and thread statuses) or a heap dump (which you can analyse with tools like https://www.eclipse.org/mat/ ) to work out what's taking up all your memory 😉 ... and if you want track what the gc process is upto, you can enable gc logging ... but visual vm is a great place to start and lets you track this data over time and draw some heap usage graphs and so on 😉
It didn't come bundled with my JVM but I also didn't have to start the JVM with any extra flags, maybe because :jvm-opts ["-Djdk.attach.allowAttachSelf"]
is all that's needed and I already have it for the clj-async-profiler to work.
I'll check out MAT and your pointers are a good starting point to do some more reading about this.
it's also good to know about jcmd
and jstack
, the first lists all the running JVMs with their process id, the second prints out the stack traces of all threads based on a process id. If a JVM is really starting to eat up all the CPU then it might not be feasible to still start visualvm and attach it, but jcmd/jstack should still work and can give you a rough idea of what it's doing.
also super useful for the opposite problem: my JVM seems to be stuck, what is it blocking on?
@U07FP7QJ0 Good point, there might not be enough CPU left to start up a heavy inspection tool. Thank you for mentioning those alternatives!
ok so I have this ~/.m2/repository/org/clojure/core.async/1.5.648/core.async-1.5.648.jar
in my classpath but when I run the REPL and do
user=>(:require [clojure.core.async])
I get a ClassNotFoundException
that should probably be:
(require 'clojure.core.async)
what's the difference between :require
and require
, I know the former is a keyword but when do I need that and when not
the (:require [clojure.core.async])
form is used when it's part of an namespace declaration. For example:
(ns my.ns
(:require [cljoure.core.async]))
so the short answer is :require
when it's inside of an (ns ...)
expression, and (require ...)
otherwise
How do I use a library/dependency from the command line when using clojure cli? Never mind, answered!
❯ clj -Sdeps '{:deps {org.clojure/core.match {:mvn/version "1.0.0"}}}'
Clojure 1.11.1
user=> (require 'clojure.core.match)
nil
user=>
ah, -Sdeps
. i see now where that is on the Deps CLI page. I think that needs a couple more examples. Thanks so much
Does anybody know if delay
’s body resources can be garbage collected after the delay body is finished executed and the result is cached? I have a use case for ‘chained’ delay’s where a delay forces the previous delay, and was wondering if this could potentially create a memory leak if I only keep around the latest delay (whose body refer’s to the previous one, but would be the only reference)
I’m not expert on GC related issues but if you have an explicit reference to essentially a linked list of delay
s I doubt they will be reclaimed/collected
the function that a delay
delays is collected after it is invoked. docstring says:
> will cache the result and return it on all subsequent force
> calls.
if you are hanging onto a realized delay, what it caches is strongly reachable
thanks @U050ECB92 , I think it is fine for my use case then, as the reference to the delay is inside the function of another’s delay (and nowhere else)
hmm doing a quick test, I thought this wouldn’t increase the memory much, but it does (looking at VisualVM), and once is resetted to nil then it goes down (by performing GC)
(comment
(def state_ (atom nil))
(dotimes [_ 10000000]
(swap! state_ (fn [d]
(delay
(force d)
(range 1e10)))))
(reset! state_ nil)
)
Did you confirm the garbage collector was run at any point?