Skip to content

Commit dba2e8e

Browse files
committed
v4.0 squashed
1 parent 325c20b commit dba2e8e

310 files changed

Lines changed: 23126 additions & 23545 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/.github export-ignore
2+
/.vscode export-ignore
3+
/.editorconfig export-ignore
4+
/.gitignore export-ignore
5+
/.gitattributes export-ignore
6+
/docker-compose.yml export-ignore
7+
/package-lock.json export-ignore
8+
/phpstan.neon export-ignore
9+
/phpunit.xml export-ignore
10+
/pint.json export-ignore
11+
/tests export-ignore

.github/workflows/tests.yml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,105 @@ jobs:
6363
- name: Install dependencies
6464
run: composer update --prefer-dist --no-interaction --no-progress
6565

66+
- name: Run Pint
67+
run: composer lint
68+
6669
- name: Run Larastan
6770
run: vendor/bin/phpstan analyse --memory-limit=512M --error-format=github
71+
72+
database:
73+
runs-on: ubuntu-latest
74+
75+
strategy:
76+
fail-fast: false
77+
matrix:
78+
include:
79+
- label: MySQL
80+
driver: mysql
81+
image: mysql:8.4
82+
port: 3306
83+
container_port: 3306
84+
username: root
85+
password: normcache
86+
options: >-
87+
--health-cmd "mysqladmin ping --password=normcache"
88+
--health-interval 5s
89+
--health-timeout 3s
90+
--health-retries 10
91+
92+
- label: PostgreSQL
93+
driver: pgsql
94+
image: postgres:17
95+
port: 5432
96+
container_port: 5432
97+
username: postgres
98+
password: normcache
99+
options: >-
100+
--health-cmd "pg_isready -U postgres -d normcache"
101+
--health-interval 5s
102+
--health-timeout 3s
103+
--health-retries 10
104+
105+
- label: MariaDB
106+
driver: mariadb
107+
image: mariadb:11.4
108+
port: 3307
109+
container_port: 3306
110+
username: root
111+
password: normcache
112+
options: >-
113+
--health-cmd "healthcheck.sh --connect --innodb_initialized"
114+
--health-interval 5s
115+
--health-timeout 3s
116+
--health-retries 10
117+
118+
name: Database / ${{ matrix.label }}
119+
120+
services:
121+
redis:
122+
image: redis:7
123+
ports:
124+
- 6379:6379
125+
options: >-
126+
--health-cmd "redis-cli ping"
127+
--health-interval 5s
128+
--health-timeout 3s
129+
--health-retries 5
130+
131+
database:
132+
image: ${{ matrix.image }}
133+
env:
134+
MYSQL_DATABASE: normcache
135+
MYSQL_ROOT_PASSWORD: normcache
136+
POSTGRES_DB: normcache
137+
POSTGRES_PASSWORD: normcache
138+
MARIADB_DATABASE: normcache
139+
MARIADB_ROOT_PASSWORD: normcache
140+
ports:
141+
- ${{ matrix.port }}:${{ matrix.container_port }}
142+
options: ${{ matrix.options }}
143+
144+
steps:
145+
- uses: actions/checkout@v6
146+
147+
- uses: shivammathur/setup-php@v2
148+
with:
149+
php-version: "8.3"
150+
extensions: redis, pdo_mysql, pdo_pgsql
151+
coverage: none
152+
153+
- name: Install dependencies
154+
run: composer update --prefer-dist --no-interaction --no-progress
155+
156+
- name: Run database contract and cascade tests
157+
env:
158+
TEST_DB_DRIVER: ${{ matrix.driver }}
159+
TEST_DB_HOST: 127.0.0.1
160+
TEST_DB_PORT: ${{ matrix.port }}
161+
TEST_DB_DATABASE: normcache
162+
TEST_DB_USERNAME: ${{ matrix.username }}
163+
TEST_DB_PASSWORD: ${{ matrix.password }}
164+
run: >-
165+
vendor/bin/phpunit
166+
tests/Integration/Contract
167+
tests/Integration/Cache/DeleteInvalidationTest.php

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ composer.lock
44
.phpunit.result.cache
55
.phpunit.cache/
66
tests/Benchmark/
7-
tests/Concerns/
87
docs
98
.worktrees/

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
---
99

10+
## [4.0.0] — 2026-08-04
11+
12+
### Added
13+
14+
- **Membership revalidation:** a cached membership survives a version bump when every version in the gap was a precise `UPDATE` whose columns are disjoint from the query's predicate and order columns. Configure with `revalidation`, and declare `protected array $volatileColumns` for columns the database writes without the statement naming them.
15+
- **Automatic result overlays:** eligible canonical queries store a complete result payload for faster warm reads and rebuild it from canonical rows when the overlay is missing.
16+
- **Unified query controls:** `dependsOn()` accepts models and table names, `tag()` groups related queries, `NormCache::invalidate()` accepts model or table targets, and `NormCache::withoutCache()` runs a whole callback, eager loads included, against the database.
17+
- **Runtime cache switch:** `normcache:disable` and `normcache:enable`, plus their facade equivalents, pause and safely resume caching across application nodes.
18+
- **Database source scopes:** `database.connections.<name>.normcache_scope` isolates shards or tenants and allows aliases for the same source to share cache state deliberately.
19+
- **Serializer selection:** choose `auto`, `php`, or `igbinary` payload serialization.
20+
21+
### Changed
22+
23+
- **BREAKING cache layout:** cache spaces were removed and Redis placement is now derived from physical tables and query groups. Cache keys changed, so v3 and v4 must not serve traffic together. Run `normcache:disable`, deploy every web and worker node, then run `normcache:enable`.
24+
- **BREAKING API consolidation:** replace `dependsOnTables()` with `dependsOn()`, legacy invalidation methods with `NormCache::invalidate()`, and model-scoped tag flushing with `flushTag('name')`.
25+
- **BREAKING flush behavior:** `normcache:flush` now always performs a global invalidation; `--model` and `--space` were removed.
26+
- Model attribute lifetime is configured with `row_ttl` / `NORMCACHE_ROW_TTL` rather than `ttl` / `NORMCACHE_TTL`, and the key-prefix variable is now `NORMCACHE_KEY_PREFIX` rather than `NORMCACHE_PREFIX`.
27+
28+
### Fixed
29+
30+
- Improved cache isolation for connection aliases, shards, tenants, and runtime database switching.
31+
- Manual and automatic invalidation now handle connection-aware table names, unknown write targets, and writes that throw after reaching the database safely.
32+
- Improved build-lock and Redis reconnect behavior when responses are lost or operations are retried.
33+
34+
### Removed
35+
36+
- Cache spaces, `$normCacheSpaces`, `space()`, the `spaces` configuration, and space-targeted flushing.
37+
- Legacy `cooldown`, `fallback`, and `fire_retrieved` options, `Builder::explain()`, and the cache-manager facade accessors (`modelCache()`, `resultCache()`, `versionStore()`, and friends).
38+
- The `ModelCacheHit`, `ModelCacheMiss`, and `CacheMetricRecorded` events.
39+
- The `stampede_wake_tokens` option and `NORMCACHE_STAMPEDE_WAKE_TOKENS`; the wake-token count is now fixed.
40+
- Environment overrides for build-lock tuning: set `building_lock_ttl` and `stampede_wait_ms` in the published config file, not `NORMCACHE_BUILDING_LOCK_TTL` / `NORMCACHE_STAMPEDE_WAIT_MS`.
41+
- The relation-specific cache classes; relation and pivot reads are cached through the same query path as everything else.
42+
43+
---
44+
1045
## [3.1.0] — 2026-07-23
1146

1247
### Added

0 commit comments

Comments
 (0)