Imported from riclolsen/json-scada (
src/cs_data_processor-go/AGENTS.md). Install upstream withnpx skills add riclolsen/json-scada --skill cs_data_processor-go. Copyright stays with the author.
DOX: src/cs_data_processor-go — Change Stream Data Processor (Go)
Purpose
Go port of src/cs_data_processor. Processes MongoDB Change Stream events for
value conversion, alarm detection, SOE logging and historian feeding. Same
process name, arguments, environment prefix and outputs as the Node.js
version, tuned for lower change-stream processing latency.
Ownership
- Shares the change stream data processing pipeline with
src/cs_data_processor. - Exactly one of the two may run per instance number — both register as
CS_DATA_PROCESSORinprocessInstances.
Local Contracts
- Language: Go (no cgo), MongoDB driver
go.mongodb.org/mongo-driver/v2 - Main entry:
main.go, binarycs_data_processor[.exe] - Arguments:
instance logLevel [configFile](same as Node.js) - Env prefix:
JS_CSDATAPROC_(see README for the full table) - Structure:
main.go— connection lifecycle, change stream, resume tokensprocess.go— conversion logic, channels, sharded worker poolwriters.go— batching writers (realtimeData, hist + SQL files, soeData)metrics.go,hrtime*.go— latency instrumentationredundancy.go,maintenance.go,specialtags.gorawdoc.go,jsutil.go— raw BSON access and JavaScript-compatible renderingconfig.go— config file and env varstools/compare-latency.js— compares two metrics snapshots
Work Guidance
- Parity first. Any change to the conversion must keep the same observable
output as
../cs_data_processor/cs_data_processor.js. The JavaScript semantics the original relies on (loose!=againstundefined, truthiness,Numberformatting,JSON.stringifyfield order) are reproduced injsutil.goandrawdoc.go— do not "clean them up". - Changing the metric names, stages or JSON layout in
metrics.gorequires the same change in../cs_data_processor/metrics.js, otherwise the comparison tool breaks. - Queues are channels; do not reintroduce polling loops. Writers batch on size or linger, whichever comes first.
- Per-point ordering is guaranteed by hashing
fullDocument._idto a worker inbox. Any new dispatch must preserve that. - Wall-clock stages (
sourceToRecv,endToEnd) must stay ontime.Now(); in-process stages must usehrNow().
Verification
go vet ./... && go test ./...— unit tests cover the JavaScript-compatible rendering (values cross-checked against real Node.js output), the histogram, and the conversion for digital/analog/double-point/bitstring/beep/SOE/ dead-band/standby/backfill cases.gofmt -l .must print nothing.- End-to-end parity: run both implementations against the same single-node
replica set with a race-free load (one update round every few hundred ms,
so
updateLookupnever races the processor), then diff the resultingrealtimeData/soeData/histdocuments and the generatedpg_hist_*.sql/pg_rtdata_*.sqlrows with timestamps normalised. They must be identical. - Latency:
node tools/compare-latency.js --reset --wait 120 http://localhost:8081 http://localhost:8082.