Replies: 3 comments 1 reply
|
Some more information, the more I increase parallelism / async threads, the worst it is. Moving from 2 to 5 threads, it basically hangs immediately |
|
/unlabel ~question |
|
@maxenced — before we go further on the BoltDB angle, could you try $ GOMAXPROCS=2 vuls server -config=... vuls2.Detect calls ospkg.Detect(..., runtime.NumCPU()), and (Side note: bbolt with ReadOnly: true uses LOCK_SH, so concurrent Could you try and report back? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Note : I first opened this as a question, but finally found some time to investigate, so converted to a bug report.
Issue
When running vuls in server mode with the vuls2 BoltDB backend, concurrent requests
cause severe performance degradation. At concurrency >= 4-5, the server effectively
hangs, taking 10+ minutes to return a single response.
Analyse
The issue seems to be a compounding BoltDB file-lock contention caused by the per-request
open/close pattern.
1. Each HTTP request opens BoltDB multiple times independently
In server.go, each request sequentially calls:
2. newDBConfig() opens the DB twice per call
detector/vuls2/db.go#L40-L53 opens BoltDB to validate metadata, then closes it — only for the caller to immediately open it again at vuls2/vuls2.go:74. This means 4 open/close cycles per request (2 in Detect, 2 in Enrich).
3. Most important one : bolt.Open() acquires an OS-level file lock
Even with
ReadOnly: true, boltdb.go:62-78 calls bolt.Open() . Multiple concurrent Open() calls on the same file serialize against each otherFrom bolt documentation :
Suggested solution
Open the BoltDB database once at server startup and share the single *bolt.DB connection across all requests. BoltDB natively supports concurrent read transactions (View()) on a single open connection — the contention comes from repeatedly calling bolt.Open()/Close(), not from concurrent reads themselves.
This would also enable a shared in-memory cache across requests, eliminating redundant reads for the same CVE data.
=== Previous question ===
/label ~bug
All reactions