Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5713f0f
feat: add core connection pool
mkbeh Aug 1, 2026
090f02a
feat: add transaction helpers and savepoints
mkbeh Aug 3, 2026
f86122c
docs: add basic pool usage example
mkbeh Aug 3, 2026
4f0b0fc
feat: add error classifiers and advisory locks
mkbeh Aug 3, 2026
4fbddaa
docs: add advisory lock example
mkbeh Aug 3, 2026
a8d47e0
feat: add pluggable pool metrics
mkbeh Aug 5, 2026
a4c2849
feat: add OpenTelemetry pool metrics
mkbeh Aug 5, 2026
5d812de
docs: add OpenTelemetry metrics example
mkbeh Aug 5, 2026
a2c0ee0
feat(cluster): add primary and replica routing
mkbeh Aug 7, 2026
4d2bdab
docs(examples): add cluster routing example
mkbeh Aug 7, 2026
2325fce
feat(shard): add topology and shard routing
mkbeh Aug 11, 2026
fddb1b5
docs(examples): add sharding example
mkbeh Aug 11, 2026
2746d72
feat(cache): add typed in-process cache
mkbeh Aug 12, 2026
a7d5b33
feat(cache): add cache statistics and metrics
mkbeh Aug 13, 2026
435d3d0
refactor(cache): refine invalidation metrics
mkbeh Aug 13, 2026
4b8178b
refactor: remove cache and move OpenTelemetry integration
mkbeh Aug 23, 2026
ad8c4b2
build: upgrade to go1.27
mkbeh Aug 23, 2026
1091c06
chore: update golangci-lint configuration
mkbeh Aug 23, 2026
b3f7c71
feat: add logging and tracing support
mkbeh Aug 24, 2026
46e9846
refactor: simplify slog adapter
mkbeh Aug 24, 2026
00eee4a
refactor: simplify cluster routing
mkbeh Aug 24, 2026
b943baa
test: add cluster coverage
mkbeh Aug 24, 2026
cae2772
refactor: simplify shard routing
mkbeh Aug 24, 2026
a2917c6
test: cover shard topology and resolvers
mkbeh Aug 24, 2026
e2af674
refactor: simplify basic example
mkbeh Aug 25, 2026
c2f3650
refactor: simplify transactions example
mkbeh Aug 25, 2026
bf83e5a
refactor: simplify advisory example
mkbeh Aug 25, 2026
1fd7ee6
refactor: simplify observability example
mkbeh Aug 25, 2026
0b9789c
refactor: observability minor fixes
mkbeh Aug 25, 2026
2a00c49
refactor: simplify cluster example
mkbeh Aug 25, 2026
1bdf20e
refactor: simplify shard example
mkbeh Aug 25, 2026
402ad5c
feat: add geographic sharding example
mkbeh Aug 25, 2026
9a1c1f9
docs: update examples overview
mkbeh Aug 25, 2026
bd029ea
docs: add initial project documentation
mkbeh Aug 25, 2026
67356c5
docs: expand usage documentation
mkbeh Aug 25, 2026
4ed8cd2
docs: add changelog
mkbeh Aug 25, 2026
3ac53fc
docs: add otelxpg usage guide
mkbeh Aug 25, 2026
d4c256c
refactor: polish core APIs and documentation
mkbeh Aug 25, 2026
a5e5650
ci: fix lint
mkbeh Aug 25, 2026
90ff06c
ci: discover lint modules dynamically
mkbeh Aug 25, 2026
6605de3
fix: support single-line requires in workspace generator
mkbeh Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2

updates:
- package-ecosystem: "gomod"
directories:
- "/"
- "/extra/*"
- "/examples/*"
schedule:
interval: "weekly"
ignore:
# Local modules are resolved through go.work during repository builds.
- dependency-name: "github.com/mkbeh/xpg"
- dependency-name: "github.com/mkbeh/xpg/*"
groups:
go-dependencies:
patterns:
- "*"
group-by: dependency-name

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
95 changes: 95 additions & 0 deletions .github/scripts/create-go-workspace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ -n "${GITHUB_WORKSPACE:-}" ]]; then
root="${GITHUB_WORKSPACE}"
else
root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
fi

include_examples=false

for arg in "$@"; do
case "${arg}" in
--with-examples)
include_examples=true
;;
*)
echo "unknown argument: ${arg}" >&2
exit 2
;;
esac
done

cd "${root}"

rm -f go.work go.work.sum

modules=(.)

while IFS= read -r -d '' mod; do
modules+=("$(dirname "${mod}")")
done < <(find ./extra -name go.mod -type f -print0 2>/dev/null | sort -z)

if [[ "${include_examples}" == "true" ]]; then
while IFS= read -r -d '' mod; do
modules+=("$(dirname "${mod}")")
done < <(find ./examples -name go.mod -type f -print0 2>/dev/null | sort -z)
fi

# The workspace is ephemeral in CI and local-only for development.
GOWORK=off go work init "${modules[@]}"

# Local modules may already require release versions such as v0.1.0 while the
# corresponding tags do not exist yet. Bind those exact requirements to the
# current checkout so all Go tooling, including go/packages-based linters,
# resolves the unpublished modules locally.
while read -r module version; do
[[ -n "${module}" && -n "${version}" ]] || continue

case "${module}" in
github.com/mkbeh/xpg)
local_dir="."
;;
github.com/mkbeh/xpg/*)
local_dir="./${module#github.com/mkbeh/xpg/}"
;;
*)
continue
;;
esac

if [[ -f "${root}/${local_dir#./}/go.mod" ]]; then
GOWORK="${root}/go.work" go work edit \
-replace="${module}@${version}=${local_dir}"
fi
done < <(
{
printf '%s\0' ./go.mod

find ./extra ./examples \
-name go.mod -type f -print0 2>/dev/null || true
} |
while IFS= read -r -d '' mod; do
awk '
$1 == "require" &&
$2 ~ /^github\.com\/mkbeh\/xpg(\/.*)?$/ &&
$3 ~ /^v[0-9]/ {
print $2, $3
next
}

$1 ~ /^github\.com\/mkbeh\/xpg(\/.*)?$/ &&
$2 ~ /^v[0-9]/ {
print $1, $2
}
' "${mod}"
done |
sort -u
)

echo "Created temporary Go workspace at ${root}/go.work"

if [[ "${WORKSPACE_DEBUG:-false}" == "true" ]]; then
GOWORK="${root}/go.work" go work edit -json
fi
60 changes: 60 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Coverage

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
GOTOOLCHAIN: local
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

jobs:
coverage:
name: Coverage
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Check out repository
uses: actions/checkout@v7

- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
check-latest: true
cache-dependency-path: |
go.sum
extra/**/go.mod

- name: Set up Task
uses: go-task/setup-task@v2

- name: Create temporary Go workspace
run: bash .github/scripts/create-go-workspace.sh

- name: Run coverage
env:
GOWORK: ${{ github.workspace }}/go.work
run: task coverage

- name: Upload coverage to Codecov
if: env.CODECOV_TOKEN != ''
uses: codecov/codecov-action@v7
with:
token: ${{ env.CODECOV_TOKEN }}
files: ./coverage.out
disable_search: true
fail_ci_if_error: true
123 changes: 123 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Lint

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
GOTOOLCHAIN: local

jobs:
modules:
name: Discover modules
runs-on: ubuntu-latest

outputs:
modules: ${{ steps.modules.outputs.modules }}

steps:
- name: Check out repository
uses: actions/checkout@v7

- name: Discover Go modules
id: modules
shell: bash
run: |
set -euo pipefail

modules="$(
{
printf '.\n'

find ./extra ./examples \
-name go.mod \
-type f \
-print |
while IFS= read -r mod; do
dirname "${mod#./}"
done
} |
sort |
jq -R -s -c 'split("\n")[:-1]'
)"

echo "modules=${modules}" >> "${GITHUB_OUTPUT}"

lint:
name: Lint (${{ matrix.module }})
needs:
- modules

runs-on: ubuntu-latest
timeout-minutes: 15

strategy:
fail-fast: false
matrix:
module: ${{ fromJSON(needs.modules.outputs.modules) }}

steps:
- name: Check out repository
uses: actions/checkout@v7

- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
check-latest: true
cache-dependency-path: |
go.sum
extra/**/go.mod
examples/**/go.mod

- name: Create temporary Go workspace
run: bash .github/scripts/create-go-workspace.sh --with-examples

- name: Verify workspace resolution
env:
GOWORK: ${{ github.workspace }}/go.work
run: |
set -euo pipefail

test "$(go env GOWORK)" = "${GITHUB_WORKSPACE}/go.work"

go list -m \
-f '{{if .Main}}{{.Path}} => {{.Dir}}{{end}}' \
all |
sed '/^$/d'

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v9
env:
GOWORK: ${{ github.workspace }}/go.work
with:
version: v2.13.1
working-directory: ${{ matrix.module }}
args: >-
--config=${{ github.workspace }}/.golangci.yml
--timeout=5m
--modules-download-mode=readonly

result:
name: Lint
if: always()
needs:
- lint
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Check lint jobs
run: test "${{ needs.lint.result }}" = "success"
Loading