Skip to content

[feature] add jq filter cache#860

Merged
ldmonster merged 2 commits intomainfrom
feat/jq-filter-cache
Apr 7, 2026
Merged

[feature] add jq filter cache#860
ldmonster merged 2 commits intomainfrom
feat/jq-filter-cache

Conversation

@ldmonster
Copy link
Copy Markdown
Collaborator

Overview

Cache compiled JQ filters: parse and compile each jqFilter expression once at hook-config load time instead of on every Kubernetes event.

What this PR does / why we need it

Every Kubernetes event that reaches a hook with a jqFilter previously triggered a full gojq.Parse + implicit compilation cycle before running the expression against the object. For hooks watching high-churn resources (Pods, Events, custom CRDs with many replicas) this is a measurable, unnecessary CPU cost that accumulates proportionally to event rate × number of monitored bindings.

This PR:

  • Introduces CompiledFilter interface in filter.go — a pre-compiled filter with a single Apply(data) ([]byte, error) method.
  • Adds CompiledJqFilter struct in apply.go backed by *gojq.Code (the compiled representation returned by gojq.Compile). A Compile(string) constructor parses and compiles the expression once. A shared collectResults helper is extracted so both the interpreted (Filter.ApplyFilter) and compiled (CompiledJqFilter.Apply) paths stay DRY.
  • Adds CompiledJqFilter filter.CompiledFilter field to MonitorConfig and a WithJqFilter(string) error method that atomically sets the raw string (kept for metadata/logging) and compiles it. Config parse errors for invalid jqFilter expressions are caught immediately at startup, not at first event.
  • Updates config parsing in config_v0.go and config_v1.go to call monitor.WithJqFilter(...) instead of plain field assignment — invalid expressions are now rejected at hook-config load time with a descriptive error.
  • In resource_informer.go, removes the two per-event jq.NewFilter() allocations and passes ei.Monitor.CompiledJqFilter directly to applyFilter. The jqFilter string is still forwarded as a separate argument purely for res.Metadata.JqFilter (used by the binding-context JSON marshaler).
  • applyFilter signature simplified from (jqFilter string, fl filter.Filter, ...) to (compiledFilter filter.CompiledFilter, jqFilterStr string, ...).

Performance impact:
gojq.Parse + gojq.Compile run once per binding at startup. Per-event cost is reduced to code.Run(data) only.

Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
@ldmonster ldmonster self-assigned this Apr 7, 2026
@ldmonster ldmonster added the enhancement New feature or request label Apr 7, 2026
Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
@ipaqsa ipaqsa added the go Pull requests that update Go code label Apr 7, 2026
@ldmonster ldmonster merged commit 37b7c71 into main Apr 7, 2026
14 checks passed
@ldmonster ldmonster deleted the feat/jq-filter-cache branch April 7, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants