Commit 972e1da
committed
perf(redis): bounded Lua VM pool with configurable max-idle cap
Replace the sync.Pool-backed luaStatePool with a buffered-channel
pool sized at a configurable cap. The previous implementation had
two operational issues visible from the production 5-node cluster:
- No operator-tunable upper bound. sync.Pool's only governor was
the Go GC; under steady high-rate EVAL load the pool retained
however many states the GC happened not to clear that cycle,
so the memory floor moved with allocation rate and GOGC.
- No saturation signal. There was no way to observe whether the
pool was being right-sized for the workload — Hits()/Misses()
showed reuse rate but never said "this many puts were rejected
because the pool was at capacity."
New pool:
- Backing: buffered chan *pooledLuaState of capacity maxIdle.
- Default cap: 64. Empirically each pooled state holds ~200 KiB
of long-lived heap (base stdlib + redis/cjson/cmsgpack closures
+ per-state snapshot tables); 64 covers redcon's typical
per-connection EVAL concurrency without retaining a long warm
tail after bursts.
- get(): non-blocking recv; on empty channel falls through to a
fresh allocation (records a Miss). Throughput is therefore not
capped — only the steady-state idle count is.
- put(): non-blocking send; on full channel drops the state,
closes it eagerly, and increments Drops. Drops > 0 is the
"raise maxIdle" diagnostic.
- Idle() and MaxIdle() exposed for metrics / admin diagnostics.
Configuration:
- main.go: new --redisLuaMaxIdleStates int flag (default 64).
- adapter.WithLuaPoolMaxIdle(n int) RedisServerOption records the
cap; NewRedisServer materializes the pool AFTER the option
loop so the cap takes effect. Test fixtures that bypass
NewRedisServer get the default via getLuaPool's lazy init.
- Non-positive values clamp to defaultLuaPoolMaxIdle so a
misconfigured --redisLuaMaxIdleStates=0 yields the default
rather than a permanently-disabled pool (which would silently
drop every put).
Caller audit (semantic change — sync.Pool → bounded channel):
- All in-tree callers of newLuaStatePool / *luaStatePool are in
adapter/redis*.go and adapter/redis_lua*_test.go. The pool's
Get/Put surface is unchanged; new accessors (Drops, Idle,
MaxIdle) are additive.
- newLuaStatePool() keeps its no-arg signature for test fixtures;
its behaviour is unchanged (defaults to defaultLuaPoolMaxIdle,
which is large enough to retain anything the existing test
suite puts back).
- The production hot path (adapter/redis_lua.go runLuaScript)
only calls Get/Put — no behavioural change.
- Behavioural difference vs sync.Pool that callers MAY observe:
the bounded pool will not retain states beyond maxIdle. The
existing TestLua_PoolRecordsReuseVsAllocation tolerates GC-
driven drops, so it stays green. No test asserted "the pool
retains states past GC," which would have been incorrect
under sync.Pool's documented contract anyway.
Tests:
- All existing TestLua_VMReuse* / TestLua_PoolSerial* /
TestLua_PoolRecordsReuseVsAllocation continue to pass.
- New TestLua_PoolBoundedOverflow locks in the cap invariant:
2*maxIdle puts retain exactly maxIdle, surplus increments
Drops, draining produces exactly maxIdle hits.
- New TestLua_PoolBoundedClampsZeroAndNegative locks in the
non-positive→default clamp so a misconfigured CLI doesn't
silently disable pooling.
Self-review (CLAUDE.md 5 lenses):
1. Data loss — N/A. Pool drops only reset/closed *lua.LStates;
no committed state lives there.
2. Concurrency — channel ops are O(1) atomic CAS; no new locks
introduced. Race tests pass.
3. Performance — channel ops are comparable to sync.Pool's per-P
slabs; the change does not alter the hot path's allocation
pattern. Pool saturation now produces eager state.Close() on
overflow, freeing per-state resources sooner than GC would.
4. Data consistency — N/A.
5. Test coverage — two new table-driven tests cover the new
bounded invariants; all existing pool tests retained.
Test command:
go test -race -count=1 -short ./adapter -- 564s, all green.
go vet ./adapter/ -- clean.
go build ./... -- clean.1 parent 12ec8ba commit 972e1da
4 files changed
Lines changed: 230 additions & 41 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
184 | 190 | | |
185 | 191 | | |
186 | 192 | | |
| |||
278 | 284 | | |
279 | 285 | | |
280 | 286 | | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
281 | 304 | | |
282 | 305 | | |
283 | 306 | | |
| |||
395 | 418 | | |
396 | 419 | | |
397 | 420 | | |
398 | | - | |
399 | | - | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
400 | 427 | | |
401 | 428 | | |
402 | 429 | | |
| |||
414 | 441 | | |
415 | 442 | | |
416 | 443 | | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
417 | 452 | | |
418 | 453 | | |
419 | 454 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
| |||
89 | 88 | | |
90 | 89 | | |
91 | 90 | | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
92 | 123 | | |
93 | | - | |
| 124 | + | |
| 125 | + | |
94 | 126 | | |
95 | | - | |
| 127 | + | |
96 | 128 | | |
97 | 129 | | |
| 130 | + | |
98 | 131 | | |
99 | 132 | | |
100 | 133 | | |
| |||
188 | 221 | | |
189 | 222 | | |
190 | 223 | | |
191 | | - | |
| 224 | + | |
192 | 225 | | |
193 | 226 | | |
194 | 227 | | |
195 | 228 | | |
196 | 229 | | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
206 | 234 | | |
207 | | - | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
208 | 251 | | |
209 | 252 | | |
210 | 253 | | |
| |||
484 | 527 | | |
485 | 528 | | |
486 | 529 | | |
487 | | - | |
488 | | - | |
489 | | - | |
490 | | - | |
491 | | - | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
492 | 534 | | |
493 | | - | |
494 | | - | |
495 | | - | |
496 | | - | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
497 | 546 | | |
498 | 547 | | |
499 | | - | |
500 | | - | |
501 | | - | |
502 | | - | |
503 | | - | |
| 548 | + | |
504 | 549 | | |
505 | | - | |
| 550 | + | |
506 | 551 | | |
507 | 552 | | |
508 | 553 | | |
509 | | - | |
510 | | - | |
511 | | - | |
512 | 554 | | |
513 | 555 | | |
514 | | - | |
515 | | - | |
516 | | - | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
517 | 561 | | |
518 | 562 | | |
519 | 563 | | |
| |||
528 | 572 | | |
529 | 573 | | |
530 | 574 | | |
531 | | - | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
532 | 585 | | |
533 | 586 | | |
534 | | - | |
535 | | - | |
536 | | - | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
537 | 591 | | |
538 | 592 | | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
539 | 602 | | |
540 | 603 | | |
541 | 604 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
627 | 627 | | |
628 | 628 | | |
629 | 629 | | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| 100 | + | |
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
| |||
1524 | 1525 | | |
1525 | 1526 | | |
1526 | 1527 | | |
| 1528 | + | |
1527 | 1529 | | |
1528 | 1530 | | |
1529 | 1531 | | |
| |||
0 commit comments