Fork me on GitHub
#lsp
<
2023-01-31
>
jussi08:01:35

Hi, bumped into a funny event with clojure-lsp, wondering if anyone has seen anything similar. Loaded largish dataset into memory for development, wrote it out to an .edn -file for later inspection/loading and clojure-lsp got funky. It's internal .lsp/.cache/db.transit.json -file grew large

-rw-r--r-- 1 jmo jmo 1.5G Jan 31 00:03 db.transit.json
and top showed that it actually went a bit wild
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND 
448457 jmo       20   0   24.2g  21.8g      0 S   4.0  69.9  13:03.63 clojure-lsp
I'm using Visual Studio Code, Calva and latest clojure-lsp , the project is a polylith monorepo with ~30 components. The db.transit.sjon file contained, repeatedly, references to one of the .edn -files I had written to disk. This happens now consistently when I load the aforementioned data set in REPL and write it to out. clojure-lsp logs are full of paths to my .edn -files. My .edn -file size 296K Jan 20 10:06 as-out-2021.edn, line count 8832.
/jmo/projects/carbonlink/tmp-data/as-out-2021.edn","^G",15,"^4","^1H","^H",1238534],["^ ","^C",1238535,"^9",13,"^5",true,"^8",1238535,"^6",1238535,"^D","product","^F",5,"^7",5,"^3","file:///home/jmo/projects/carbonlink/tmp-data/as-out-2021.edn","^G",13,"^4","^1H","^H",1238535],["^ ","^C",1238536,"^9",8,"^5",true,"^8",1238536,"^6",1238536,"^D","id","^F",5,"^7",5,"^3","file:///home/jmo/projects/carbonlink/tmp-data/as-out-2021.edn","^G",8,"^4","^1H","^H",1238536],["^ ","^C",1238537,"^9",13,"^5",true,"^8",1238537,"^6",1238537,"^D","comment","^F",5,"^7",5,"^3","file:///home/jmo/projects/carbonlink/tmp-data/as-out-2021.edn","^G",13,"^4","^1H","^H",1238537],["^ ","^C",1238538,"^9",17,"^5",true,"^8",1238538,"^6",1238538,"^D","productCode","^F",5,"^7",5,"^3","file:///home/jmo/projects/carbonlink/tmp-data/as-out-2021.edn","^G",17,"^4","^1H","^H",1238538],["^ ","^C",1238539,"^9",14,"^5",true,"^8",1238539,"^6",12385
After removing the db.transit.json file and trying again, this situation occurred again, clojure-lsp does not currently hog one CPU completely atm as it did yesterday, but the memory footprint is large.
451360 jmo       20   0   14.2g  12.2g   3284 S   6.6  39.2  29:15.79 clojure-lsp
Any ideas what this could be? UPDATE Left my laptop for a few minutes and this is now the situation
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                     
 459197 jmo       20   0 5027424   4.6g  61440 S  98.7  14.8  10:43.99 clojure-lsp   
Had to kill the process manually, killing Calva did not end the process.

jussi09:01:47

Next, I'll move all my .edn files away from my project directory to see if it has any effect. (will be AFK for few hours though)

pez09:01:41

I think clojure-lsp will initially allocate more memory when the cache is empty, and then cool it when that is done. Still 4.6 gig seems like a lot. I have 7 projects open and none of the clojure-lsp processes consume more than 500 meg.

jussi09:01:26

OS is Linux camel 5.17.12-100.fc34.x86_64 #1 SMP PREEMPT Mon May 30 17:47:02 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

jussi09:01:02

And 4.6 gig is not the largest memory footprint, at one time it consumed 14.2G...

borkdude09:01:10

@U0267SNCPEY Is it possible to make a repro repository so clojure-lsp maintainers can reproduce this locally?

borkdude09:01:37

We've seen this issue before but we haven't managed to reproduce this, which is necessary to be able to fix it

jussi10:01:02

@U04V15CAJ will try when back at work 👍:skin-tone-2:

ericdallo10:01:50

Hum, since latest release clojure-lsp now care about edn and quoted forms l analysis, maybe there is some corner cases we don't know, a repro would certainly help

borkdude10:01:16

Perhaps there is a loads of keyword + symbol analysis stored in that single transit file?

ericdallo10:01:40

Probably, but we load it once per startup

borkdude10:01:34

but all of this analysis is in memory right

borkdude10:01:46

if you have a gazillion keywords/symbols in an EDN file, that's a huge bucket

jussi13:01:32

I moved my project specific dev tmp file directory away and the problem disappears. I had several .edn-files in there totalling in 10 238 652 lines of data 🙈

😮 2
ericdallo13:01:12

Glad you fixed it, if the file was in the source-paths, clojure-lsp would consider it and analyze it indeed

jussi13:01:51

The directory was in the project root, have to check my config because I don't remember adding it to the project path (polylith project). I did use the files from my comment code.

borkdude13:01:36

When you edit the files themselves, they're also analyzed right

jussi13:01:56

Read in as edn yes

borkdude13:01:06

I mean, edit in your editor

borkdude13:01:13

and analyzed as in analyzed by clj-kondo

pez13:01:33

Then it wouldn't matter if they were moved away?

jussi13:01:41

And reprocessed, since I do the calculation on data that I don't want to use internet to fetch evertyime. I usually do not open them in editor, since they are large

jussi13:01:06

I mean that I dump data from a REST API locally for dev purposes

pez13:01:10

What you do with them in the REPL doesn't matter for clojure-lsp.

borkdude13:01:13

If they are not on the classpath and you're not opening them in your editor, I don't see how they would matter for clojure-lsp, unless clojure-lsp does too much

borkdude13:01:45

like the watcher functionality maybe? does that also watch files not on the classpath?

ericdallo13:01:41

maybe, it depends on the editor

ericdallo13:01:57

if there is a didChangeWatchedFiles for that URI, yes

jussi13:01:30

Checked the classpath, my project root is not included nor the directory I used for storing the data dumps

ericdallo13:01:06

Please, check <https://clojure-lsp.io/troubleshooting/#client-server-log%7Cclient&lt;-&gt;server> communication and look for mentions of that file

2
jussi14:01:00

After few minutes, CPU usage dropped but the memory footprint remains

491112 jmo       20   0 8920504   8.3g  72000 S   2.6  26.7   8:21.93 clojure-lsp

jussi14:01:53

So, I moved the problematic directory back to the project root, started Calva and I have the autostart configured for clojure-lsp so it immediately started to hog m emory

ericdallo14:01:14

that is the server logs, we need the client<->server logs, the exact link I mentioned

jussi14:01:38

ah, my bad!

jussi14:01:40

It seems to browse through my temporary data dump files.

[Trace - 16:32:41] Received notification 'textDocument/publishDiagnostics'.
Params: {
    "uri": "file:///home/jmo/projects/carbonlink/invoice-51456979.edn",
    "diagnostics": []
}


[Trace - 16:32:41] Received notification 'textDocument/publishDiagnostics'.
Params: {
    "uri": "file:///home/jmo/projects/carbonlink/tmp-data/invoice-48713344.edn",
    "diagnostics": []

jussi14:01:21

log has 14300 lines and it includes some of our code (dev-helpers, etc) is there a specific part that is of interest?

borkdude14:01:35

Hmm, maybe this is also relevant for the @U02CX2V8PJN issue

Thierry14:01:15

For me it only does this when I actually open a large file when it open in the main window in VSCode. I added the following setting to .clj-kondo/config.edn: :output {:exclude-files ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**" "/resources/clients/**"]} This stops it from evaluating it before hand

ericdallo14:01:16

@U0267SNCPEY textDocument/publishDiagnostics means server published those diagnostics after analyzing it, we need to know what is triggering the analysis: • if it's on classpath, it will be triggered on startup (probably this case, I see "/home/jmo/projects/carbonlink" in your server logs) • if the file is opened we lint and publish diagnostics • if the file is watched on client and client send to server via didChangeWatchedFiles

jussi14:01:50

"workspaceFolders": [
        {
            "uri": "file:///home/jmo/projects/carbonlink",
            "name": "carbonlink"
        }
    ],
If it starst its recrusive search based on that directory, yes then it will find my data dump files and analyzes them

ericdallo14:01:04

hum, I don't think that's the issue, clojure-lsp run a external command to retrieve the classpaths, for a polylith project should be something like: clj -A:dev:test -Spath , could you run that in your terminal and check if the project root is there?

jussi15:01:52

bases/api/test/resources
src
/home/jmo/projects/carbonlink/components/airlines/src
/home/jmo/projects/carbonlink/components/airlines/resources
/home/jmo/projects/carbonlink/components/airports/src
/home/jmo/projects/carbonlink/components/airports/resources
/home/jmo/projects/carbonlink/bases/api/src
/home/jmo/projects/carbonlink/bases/api/resources
/home/jmo/projects/carbonlink/components/categorization/src
/home/jmo/projects/carbonlink/components/categorization/resources
/home/jmo/projects/carbonlink/bases/cli/src
/home/jmo/projects/carbonlink/bases/cli/resources
/home/jmo/projects/carbonlink/components/co2e/src
/home/jmo/projects/carbonlink/components/co2e/resources
/home/jmo/projects/carbonlink/components/co2e-factor/src
/home/jmo/projects/carbonlink/components/co2e-factor/resources
/home/jmo/projects/carbonlink/components/config/src
/home/jmo/projects/carbonlink/components/config/resources
/home/jmo/projects/carbonlink/components/currency/src
/home/jmo/projects/carbonlink/components/currency/resources
/home/jmo/projects/carbonlink/components/db/src
/home/jmo/projects/carbonlink/components/db/resources
/home/jmo/projects/carbonlink/bases/dev-helper/src
/home/jmo/projects/carbonlink/bases/dev-helper/resources
/home/jmo/projects/carbonlink/components/yyy/src
/home/jmo/projects/carbonlink/components/yyy/resources
/home/jmo/projects/carbonlink/components/einvoice/src
/home/jmo/projects/carbonlink/components/einvoice/resources
/home/jmo/projects/carbonlink/components/emce/src
/home/jmo/projects/carbonlink/components/emce/resources
/home/jmo/projects/carbonlink/components/envimat/src
/home/jmo/projects/carbonlink/components/envimat/resources
/home/jmo/projects/carbonlink/components/espoo-opendata/src
/home/jmo/projects/carbonlink/components/espoo-opendata/resources
/home/jmo/projects/carbonlink/components/expense-csv/src
/home/jmo/projects/carbonlink/components/google-auth/src
/home/jmo/projects/carbonlink/components/google-auth/resources
/home/jmo/projects/carbonlink/components/helsinki-opendata/src
/home/jmo/projects/carbonlink/components/helsinki-opendata/resources
/home/jmo/projects/carbonlink/components/hus-opendata/src
/home/jmo/projects/carbonlink/components/hus-opendata/resources
/home/jmo/projects/carbonlink/components/microsoft/src
/home/jmo/projects/carbonlink/bases/mssql-digger/src
/home/jmo/projects/carbonlink/bases/mssql-digger/resources
/home/jmo/projects/carbonlink/components/zzz/src
/home/jmo/projects/carbonlink/components/zzz/resources
/home/jmo/projects/carbonlink/components/oidc/src
/home/jmo/projects/carbonlink/components/pathom/src
/home/jmo/projects/carbonlink/components/xxx/src
/home/jmo/projects/carbonlink/components/xxx/resources
/home/jmo/projects/carbonlink/components/railways/src
/home/jmo/projects/carbonlink/components/railways/resources
/home/jmo/projects/carbonlink/components/util/src
/home/jmo/projects/carbonlink/components/util/resources
/home/jmo/projects/carbonlink/bases/xtdb-inspector/src
/home/jmo/projects/carbonlink/bases/xtdb-inspector/resources
/home/jmo/.m2/repository/kaocha-noyoda/kaocha-noyoda/2019-06-03/kaocha-noyoda-2019-06-03.jar
/home/jmo/.gitlibs/libs/lambdaisland/kaocha/6bac06a47235930a84fc4167d475d2ed1f1ce7a2/src
/home/jmo/.gitlibs/libs/lambdaisland/kaocha/6bac06a47235930a84fc4167d475d2ed1f1ce7a2/resources
/home/jmo/.m2/repository/org/clojure/clojure/1.11.1/clojure-1.11.1.jar
...

jussi15:01:35

Rest of the paths were pointing to .m2/, also redacted few customer specific names

ericdallo15:01:43

so no project root right?

jussi15:01:54

Not that I could find no

jussi15:01:43

Did run (->> (java.lang.System/getProperty "java.class.path") (re-seq #"[^;:]+") (map println) dorun) in REPL too with the same result

ericdallo15:01:49

could you: • rm -r .lsp/.cache • restart the server • paste server logs, especially the part that says the command it will run to retrieve the classpaths and the classpath found

2
jussi15:01:23

INFO [clojure-lsp.classpath:103] - Finding classpath via `/usr/local/bin/clojure -A:test:dev -Spath
`

jussi15:01:54

same result with that exact cmd

jussi15:01:03

just a sec

jussi15:01:05

Nope, now that it didn'n use the cached classpath the root dir is not there.

jussi15:01:44

So, with a fresh start, .lsp/.cache removed it seems to have a sane classpath.

jussi15:01:08

(gotta run now, will be back in few hours perhaps, tomorrow at latest)

👍 2
ericdallo15:01:00

yeah, weird how that folder was in the classpath, but that should be enough to not scan the file unnecessarily

snoe17:01:56

There are plenty of instances where I've seen edn in the classpath, seems like if we started analyzing them we should have a config flag to not do so.

ericdallo17:01:58

yeah, maybe, it should be rare to have huge edn files, but we should have a flag to not analyze indeed

ericdallo17:01:11

@U0267SNCPEY feel free to create an issue about that

2
borkdude17:01:36

or maybe :exclude-files to never analyze those paths (with regex patterns, similar to in clj-kondo, matched via re-find

👍 2
ericdallo17:01:07

yes, looks more extensible

ericdallo21:01:23

I just pushed a new setting :paths-ignore-regex doing that ☝️, so now it's possible to exclude from linting/analyzing specific paths by regex, available at #C032YH7P0R2

borkdude21:01:46

is :paths-ignore-regex a single regex or a vector of regex-patterns?

ericdallo21:01:19

A vector, following source-paths-ignore-regex existing setting standard

jussi07:02:42

@UKFSJSM38 do you still need an issue or is everything ok for clojure-lsp development?

Thierry07:02:37

I will test this new setting aswel!

ericdallo10:02:56

No issue needed anymore, would be nice if you could test it

jussi10:02:12

Sure can!

Thierry11:02:28

:paths-ignore-regex <- this setting, do I put it in my workspace file, in a new config.edn in .lsp, in the config.edn in .kondo or somewhere else?

ericdallo11:02:34

It's a clojure-lsp setting, so in .lsp/config.edn

Thierry11:02:53

Okay thanks

Thierry11:02:14

last nightly exe crashes for me, will try the jar file now.

[Error - 12:19:04] The Clojure Language Client server crashed 5 times in the last 3 minutes. The server will not be restarted. See the output for more information.
[Error - 12:19:04] Server initialization failed.
  Message: Pending response rejected since connection got disposed
  Code: -32097 

Thierry11:02:39

Tried with setting version to nightly without an lsp path aswell

Thierry11:02:34

.jar file starts without issues (using batch file to start it)

Thierry11:02:16

Running without batch file now, didnt get a connection to the process. Will report back how this works

jussi11:02:45

Running Calva now with the nightly build (`.jar`), findings so far • "." is found on source-paths as well as on classpath - I have no idea why? • Without the new config option, the problem persists • With the new option set to {:paths-ignore-regex ["tmp.*"]} the startup takes some time as expected, but the symptoms are gone (my evil directory is tmp-data)

Thierry12:02:56

I tried the following. Mind you, these are all folders containing either large files or files I don't want analyzed as they are not part of the project. Having lsp-version set to latest: .clj-kondo/config.edn: :output {:exclude-files ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**" "/resources/clients/**"]} Memory usage on startup is 786MB~1GB and stays around that size. .clj-kondo/config.edn: :output {:exclude-files ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**"]}If I remove one of the excluded folders from this list should increase the memory usage? But for some reason it doesn't and the startup memory is around 500MB~1GB but goes down to about 420MB after a minute or so. If I remove the output exclude-files line completely the startup memory is around 650MB~700MB and stays at that. Having lsp-path set to the latest nightly jar (exe file crashes): .clj-kondo/config.edn: :output {:exclude-files ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**" "/resources/clients/**"]} .lsp/config.edn: {:paths-ignore-regex ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**" "/resources/clients/**"]} This makes the lsp-server crash startup progress at different percentages, restarts, tries again and crashes again.

[Error - 13:05:02] Server initialization failed.
  Message: Internal error
  Code: -32603 
[object Object]
[Error - 13:05:02] Clojure Language Client client: couldn't create connection to server.
  Message: Internal error
  Code: -32603 
[object Object]
If I set the .lsp/config.edn to use actual regex :face_palm: it doesn't crash and memory usage goes up to about 1.2GB. .clj-kondo/config.edn: :output {:exclude-files ["dev-resources/**" "../_docs-code/**" "..\\_docs-code\\**" "/resources/clients/**"]} .lsp/config.edn: {:paths-ignore-regex ["docs-code.*" "clients.*" "dev-resources.*"]} If I remove the same folder from .clj-kondo/config.edn the memory usage stays around 1.1GB. So in short, for me the best option for now is using the latest clojure-lsp (without config.edn) and remove one folder (no clue why) from the kondo config.edn and memory stays around 684MB

ericdallo12:02:32

if you use the new clojure-lsp setting you don't need to change anything on kondo config as clojure-lsp won't even pass to kondo those paths.

ericdallo12:02:16

I don't know why it's crashing for windows the nightly, needs more debugging and I don't have a windows machine nearby unfortunately

ericdallo12:02:06

maybe there is something to improve on the new setting regex https://github.com/clojure-lsp/clojure-lsp/blob/master/lib/src/clojure_lsp/kondo.clj#L257? I can take a closer look later trying to repro with your paths that crash

Thierry12:02:02

There's probably something else wrong with my configuration, I'm not getting any warnings or errors in the PROBLEMS tab in VSCode, not even if I make intentional errors and reload vscode.

ericdallo12:02:37

if those paths are ignored in the new setting, that's expected.

Thierry12:02:53

yes, but not even in project files

ericdallo12:02:26

probably something with the regex

borkdude12:02:41

user=> (re-pattern ""..\\_docs-code\\**")
Syntax error reading source at (REPL:1:29).
Unsupported character: \\_docs-code
Syntax error reading source at (REPL:1:33).
Unsupported character: \\**

borkdude12:02:59

@UKFSJSM38 I think it might be nice if you use fs/unixify so you would only have to provide only one regex for all OSes

👍 2
borkdude12:02:55

(this is a new function in babashka.fs)

Thierry12:02:55

I just noticed that too, this isn't logged anywhere tho. It only popped up for me when I (deliberately) activated the separate clj-kondo extension. I have now disabled that again and edited the regex and the linter is working again

borkdude12:02:43

@U02CX2V8PJN Try this:

user=> (re-pattern "..\\\\_docs-code\\\\.*")
#"..\\_docs-code\\.*"

ericdallo12:02:49

I'll try to add log of what paths matched the regex when ignored

borkdude12:02:50

** isn't valid in a Java regex

Thierry12:02:29

yes thats my bad, I used .gitignore entries :face_palm:

Thierry12:02:33

Is there a setting that makes clojure-lsp not start automatic? I probably did something while testing and now I have to start it manually everytime

borkdude12:02:49

Apparently you can use this for literal strings:

"\\Qc:\\foo\\E"

borkdude12:02:06

But this doesn't work, never mind:

user=> (re-find (re-pattern (java.util.regex.Pattern/quote "c:\\foo")) "foo")
nil

borkdude12:02:46

oh of course:

user=> (re-find (re-pattern (java.util.regex.Pattern/quote "c:\\foo")) "c:\\foo\\bar")
"c:\\foo"

Thierry12:02:58

Have to click this and then click run otherwise it just wont start

borkdude12:02:24

oh a great, a path with both / and \ ?

borkdude12:02:59

well, calling fs/unixify on that should take care of it

ericdallo12:02:37

Pushed a commit using fs/unixify, should be available soon on #C032YH7P0R2

borkdude13:02:12

I think you should use re-find here: re-matches

borkdude13:02:43

and also I think you still need to match against the original path too in case Windows users write \\

borkdude13:02:56

only on Windows, which you can check with fs/windows?

Thierry13:02:23

@U04V15CAJ I did not add the leading / in the clojure-lsp prick a project thing. For some reason it's now seeing all those folders as project folders? Could this be the reason why clojure-lsp isnt automatically starting? It did before

Thierry13:02:03

I don't get it, this is set correctly and still it doesn't auto start.

ericdallo13:02:58

that looks like the Calva regression introduced on recent release, check #CBE668G4R

Thierry13:02:54

Going 1 version before the one released an hour ago makes it auto start again

Thierry09:02:05

I have a question about :paths-ignore-regex not ignoring the paths in the regex making lsp read and scan files it shouldn't causing this [Trace - 10:46:25] Received response 'initialize - (0)' in 601009ms. 10 minute startup and 10GB of memory usage :melting_face: I have this in my .lsp/config.edn : :paths-ignore-regex ["clients.*" "dev-resources.*" "docs-code.*"] but for some reason it still scans stuff in the folders within clients.* . I double checked this on http://regex101.com and with (re-find (re-pattern #"clients.*") "resources/clients/16/2023-02-15T13.00.16-update-sync-contextdata.clj") which is an actual path to one of those files and they check out. That file (and others) in the resources/clients/* folder and sub folder still get scanned. Am I doing something wrong @UKFSJSM38?

ericdallo11:02:31

That setting doesn't exist, I think you meant source-paths-ignore-regex , even so, does those folder have clj or edn files you want to ignore? 600.000ms looks a lot indeed

Thierry11:02:11

ahh changes have been made, thanks for pointing that out!

armed16:01:52

Hi, quick question. Documentation says:

Note that clojure-lsp will make this scan to save the cache when:

The project has no cache (.lsp/.cache)
The project deps file (project.clj for example) changed.
The clj-kondo config has changed.
Will clojure-lsp recalculate classpath if modified/changed time is updated for deps.edn even if file contents are the same? Basically, I want to force recalculate classpaths for the currently running lang server. Or what is the proper way to do it?

armed16:01:20

Or do clojure-lsp monitor changes in .lsp/config.edn and update cp?

ericdallo16:01:58

If the file sha changed, yes

borkdude16:01:10

Either way you can restart the lsp server with lsp-workspace-restart and then you will see the new classpath being used

ericdallo16:01:02

Yeah, keep in mind that no changes are monitored if you change the deps file, you still need to restart aerver

armed16:01:35

got it thanks