class

Noir::ReadPool

Inherits Reference < Object

Reads files on a small pool of threads.

The detect walk used to read every file on the one thread that also runs detection, so each open/read/close stalled everything else — on a warm page cache macOS spends ~50µs of syscall time per file, and a cold one waits on the disk. Reads are independent and touch no shared state, so they can run in parallel; everything done with a file's content stays where it was.

Callers get a reply channel per submitted path and receive from those in whatever order they need — the detector receives them in walk order, so registration order, detector dispatch and the content cache see exactly the sequence a sequential walk produced.

A worker never blocks on a reply (each reply channel holds one outcome), and every submitted path gets exactly one outcome, errors included: a missing reply would leave the receiver waiting forever.

Constructors

new(workers : Int32 = ReadPool.worker_count, passive_rules : Array(PassiveScan) = [] of PassiveScan)

passive_rules run on every file that reads as text, on the pool's threads: matching is a pure function of the content and the (immutable) rules, and it was most of what the detect workers spent their time on under -P.

Source

Class methods

worker_count

The threads are Noir::WorkerThreads', shared with the other pure work a scan hands off, so the process never runs more than one small pool.

Source

Instance methods

close

No more submissions; returns once every worker has finished.

Source
submit(path : String) : Channel(Outcome)

Queue path for reading. The returned channel yields its Outcome.

Source

Nested types