feat: import the c3e cache library as a standalone module#1
Merged
Conversation
Extract the dependency-aware caching layer (previously pkg/c3e in svc-qu3ry-core) into its own module, github.com/slashdevops/c3e, so it can be released and consumed as an external dependency. Contents: - Source: CacheManager, SafeCacheManager (stale-while-revalidate, singleflight, TTL jitter, query-timeout fallback), TypedSafeCacheManager, observability hooks, and an injectable slog logger. - Module: go.mod (go 1.26, valkey-go v1.0.76, x/sync v0.22.0) + go.sum. - CI/config: pr/release/codeql workflows (with a Valkey service so the cache tests run for real), .golangci.yaml, .testcoverage.yml, dependabot, funding, release-notes, SECURITY.md. - Docs: split the monolithic README into docs/ (architecture, usage, configuration, observability, best-practices, limitations) with Mermaid diagrams; slimmed the README to install + a quick start + two diagrams + links. Fixed inaccuracies (Go 1.26, valkey v1.0.76, Apache-2.0, dropped the fabricated benchmark table). Fixes uncovered once the suite runs against a real Valkey: - GetWithEncoder built SafeCacheManager as a struct literal, bypassing the constructor, so logger was nil (panic on the first Warn) and QueryTimeout was 0 (an already-expired lookup context forcing every read onto the fallback path). Apply the constructor defaults on that path and add a nil-safe logger accessor. - Made ExampleGetWithEncoder self-contained (it read a JSON-cached key with the Gob decoder) and shrank the stale-while-revalidate integration case from a 65s wall-clock wait to ~2.5s via a short soft TTL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Comment on lines
+13
to
+102
| runs-on: ubuntu-latest | ||
|
|
||
| services: | ||
| valkey: | ||
| image: valkey/valkey:latest | ||
| ports: | ||
| - 6379:6379 | ||
| options: >- | ||
| --health-cmd "valkey-cli ping" | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version-file: ./go.mod | ||
|
|
||
| - name: Summary Information | ||
| run: | | ||
| echo "# Pull Request Summary" > $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Repository:** ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Pull Request:** ${{ github.event.pull_request.title }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Author:** ${{ github.event.pull_request.user.login }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Branch:** ${{ github.event.pull_request.head.ref }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Base:** ${{ github.event.pull_request.base.ref }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Commits:** ${{ github.event.pull_request.commits }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Changed Files:** ${{ github.event.pull_request.changed_files }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Additions:** ${{ github.event.pull_request.additions }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Deletions:** ${{ github.event.pull_request.deletions }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| - name: Tools and versions | ||
| run: | | ||
| echo "## Tools and versions" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| ubuntu_version=$(lsb_release -a 2>&1 | grep "Description" | awk '{print $2, $3, $4}') | ||
| echo "Ubuntu version: $ubuntu_version" | ||
| echo "**Ubuntu Version:** $ubuntu_version" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| bash_version=$(bash --version | head -n 1 | awk '{print $4}') | ||
| echo "Bash version: $bash_version" | ||
| echo "**Bash Version:** $bash_version" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| git_version=$(git --version | awk '{print $3}') | ||
| echo "Git version: $git_version" | ||
| echo "**Git Version:** $git_version" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| go_version=$(go version | awk '{print $3}') | ||
| echo "Go version: $go_version" | ||
| echo "**Go Version:** $go_version" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| - name: Lint | ||
| uses: golangci/golangci-lint-action@v8 | ||
| with: | ||
| version: latest | ||
|
|
||
| - name: Lines of code | ||
| run: | | ||
| echo "## Lines of code" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| go install github.com/boyter/scc/v3@latest | ||
| scc --format html-table . | tee -a $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| - name: test | ||
| env: | ||
| C3E_TEST_VALKEY_ADDR: localhost:6379 | ||
| run: | | ||
| echo "### Test report" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| go test -race -coverprofile=coverage.txt -covermode=atomic -tags=integration ./... | tee -a $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| - name: test coverage | ||
| run: | | ||
| echo "## Test Coverage" >> $GITHUB_STEP_SUMMARY | ||
|
|
||
| go install github.com/vladopajic/go-test-coverage/v2@latest | ||
|
|
||
| # execute again to get the summary | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### Coverage report" >> $GITHUB_STEP_SUMMARY | ||
| go-test-coverage --config=./.testcoverage.yml | sed 's/PASS/PASS ✅/g' | sed 's/FAIL/FAIL ❌/g' | tee -a $GITHUB_STEP_SUMMARY |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Imports the dependency-aware caching layer (previously
pkg/c3einsvc-qu3ry-core, hardened across PRs #298–#304) into its own module so it can be released asgithub.com/slashdevops/c3eand consumed externally.What's in here
Library
CacheManager(low-level Valkey ops + dependency graph)SafeCacheManager— stale-while-revalidate, singleflight thundering-herd protection, TTL jitter, bounded query-timeout fallbackTypedSafeCacheManager[T]/GetSafe[T]— compile-time type safety*slog.Logger+ metrics/tracingHooks(OnGet/OnRefresh/OnInvalidate,Resultenum)Module & CI
go.mod(go 1.26,valkey-gov1.0.76,x/syncv0.22.0) +go.sumpr,release,codeql— the test jobs run a Valkey service container so the cache tests execute for real (-tags=integration).golangci.yaml,.testcoverage.yml(gate 75% total / 70% package; currently 87.8%),dependabot.yml,FUNDING.yml, release-notes config,SECURITY.mdDocs
docs/: architecture, usage, configuration, observability, best-practices, limitations — with Mermaid diagramsBug fixes surfaced by running against a real Valkey
GetWithEncoderbuiltSafeCacheManageras a struct literal, bypassing the constructor →loggerwasnil(panic on firstWarn) andQueryTimeoutwas0(already-expired lookup context, forcing every read onto the fallback path). Now applies the constructor defaults on that path, plus a nil-safe logger accessor as defense-in-depth.ExampleGetWithEncoderwasn't hermetic — it read a JSON-cached key with the Gob decoder (unexpected EOF). It now starts from a clean slate.Verification
go build,go vet(both tag sets),golangci-lint(0 issues),go test -race(unit +-tags=integrationagainst Valkey), coverage gate — all green locally.After merge: tag v1.0.1, then
svc-qu3ry-coreswaps itspkg/c3eimport for the external module (separate PR).🤖 Generated with Claude Code