Skip to content

Improvements#87

Merged
mostafa merged 12 commits into
mainfrom
improvements
Feb 21, 2026
Merged

Improvements#87
mostafa merged 12 commits into
mainfrom
improvements

Conversation

@mostafa

@mostafa mostafa commented Feb 21, 2026

Copy link
Copy Markdown
Member

Ticket(s)

Resolves #64

Description

Bug fixes, code quality improvements, dependency updates, CI hardening, and expanded test coverage.

Bug fixes:

  • Fix return -> continue in UpdateCache goroutine — a single transient error (e.g. empty database name) permanently killed all server-response caching for the plugin's lifetime
  • Fix IsCacheNeeded receiving the raw cache key instead of the parsed SQL query string
  • Fix ExitOnStartupError being read before it was set in main.go
  • Guard against close(nil) channel panic when config is nil
  • Fix double-counting of CacheMissesCounter in OnTrafficFromClient

Code quality:

  • Add CacheErrorsCounter to separate Redis operation errors from genuine cache misses
  • Extract duplicated startup error-handling into handleStartupError helper
  • Add config validation with sensible defaults and warning logs for redisURL, expiry, scanCount
  • Add WaitGroup for graceful UpdateCache goroutine shutdown
  • Fix typos: cachedRespnseKey -> cachedResponseKey, DateFucntion -> DateFunction

Dependencies:

  • Update gatewayd-plugin-sdk v0.4.3 -> v0.4.4, gatewayd v0.10.2 -> v0.11.0, and all direct deps
  • Migrate from deprecated go-redis/redis/v8 to redis/go-redis/v9

CI:

  • Bump actions/checkout to v4, actions/setup-go to v5, softprops/action-gh-release to v2
  • Add govulncheck security scanning step

Tests (coverage 50% -> 64%):

  • TestIsCacheNeeded — table-driven test for all PostgreSQL date/time functions
  • TestOnClosed / TestOnClosedNilClient — connection cleanup
  • TestInvalidateDML / TestInvalidateDMLSelectIgnored — DML cache invalidation
  • TestUpdateCacheContinuesOnError — validates goroutine resilience after the return -> continue fix

Related PRs

None

Development Checklist

  • I have added a descriptive title to this PR.
  • I have squashed related commits together.
  • I have rebased my branch on top of the latest main branch.
  • I have performed a self-review of my own code.
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added docstring(s) and type annotations to my code.
  • I have made corresponding changes to the documentation (docs).
  • I have added tests for my changes.

Legal Checklist

@mostafa mostafa self-assigned this Feb 21, 2026
The UpdateCache goroutine used `return` instead of `continue` on
error paths (empty database, query parse failure, table extraction
failure). A single transient error would permanently kill the
goroutine, stopping all server-response caching for the plugin's
lifetime. Resolves #64.
IsCacheNeeded was called with the full cache key (server:db:request_bytes)
instead of the actual SQL query string. Date/time function detection
against raw binary bytes was unreliable. Now the query is parsed first
via GetQueryFromRequest and uppercased before checking.
Move config field assignments (including ExitOnStartupError) before
the API client initialization block so the flag is set when first
checked. Also guard the deferred channel close to prevent a panic
when config is nil and the channel was never initialized.
Introduce a dedicated CacheErrorsCounter to separate Redis operation
failures from genuine cache misses. Previously CacheMissesCounter was
incremented for SET/DEL/SCAN errors, making the metric unreliable.
Also fix double-counting in OnTrafficFromClient where a single miss
incremented CacheMissesCounter twice. Fix typos: cachedRespnseKey ->
cachedResponseKey, DateFucntion -> DateFunction.
Replace three copies of the ExitOnStartupError check + manual close +
os.Exit(1) pattern with a single handleStartupError helper that
accepts variadic io.Closer resources. Reduces boilerplate and
ensures consistent behavior across all startup error paths.
Previously cast.To* silently returned zero-values for invalid config.
Now redisURL, expiry, and scanCount are validated with warnings and
defaults applied when values are missing or invalid.
Add a WaitGroup to the Plugin struct so the UpdateCache goroutine
signals completion when the channel is closed, allowing the process
to drain pending cache updates before exit. Tests updated to use
the same mechanism.
…rect deps

SDK v0.4.4 brings redis/go-redis/v9, go-plugin v1.7.0, pgx/v5 v5.8.0,
grpc v1.79.1, and protobuf v1.36.11. Also updates miniredis v2.36.1,
sentry v0.42.0, cast v1.10.0, testify v1.11.1, and prometheus v1.23.2
via make update-direct-deps.
Replace deprecated github.com/go-redis/redis/v8 with the maintained
github.com/redis/go-redis/v9. Updated import paths in plugin.go,
main.go, plugin_test.go, and the depguard config in .golangci.yaml.
Bump actions/checkout to v4, actions/setup-go to v5 (Node 20),
and softprops/action-gh-release to v2. Add govulncheck step to the
test workflow for security scanning. setup-go v5 includes built-in
module caching.
…esilience

- TestIsCacheNeeded: table-driven test covering all PostgreSQL date/time
  functions plus positive cases (SELECT, INSERT, empty)
- TestOnClosed: verifies client-to-database key cleanup on connection close
- TestOnClosedNilClient: verifies graceful handling of nil client
- TestInvalidateDML: verifies INSERT invalidates cached SELECT responses
  and their table index keys
- TestInvalidateDMLSelectIgnored: verifies SELECT queries don't trigger
  invalidation
- TestUpdateCacheContinuesOnError: confirms the goroutine survives errors
  and processes subsequent messages (validates the return->continue fix)
Sort imports alphabetically to satisfy gci linter. Reduce nestif
complexity in UpdateCache by inverting the caching precondition
into an early continue.
@mostafa mostafa merged commit 0611dcb into main Feb 21, 2026
3 checks passed
@mostafa mostafa deleted the improvements branch February 21, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix bug in handling traffic

1 participant