Skip to content

feat: make preventOverlapping lock TTL configurable#121

Open
lunetics wants to merge 1 commit intocrunzphp:3.10from
lunetics:feature/configurable-lock-ttl
Open

feat: make preventOverlapping lock TTL configurable#121
lunetics wants to merge 1 commit intocrunzphp:3.10from
lunetics:feature/configurable-lock-ttl

Conversation

@lunetics
Copy link

@lunetics lunetics commented Feb 10, 2026

Summary

  • Add optional int $lockTtl = 30 parameter to preventOverlapping() (backward compatible)
  • Store value in new $lockTtl property, use it in createLockObject() instead of hardcoded $ttl = 30
  • Add 2 unit tests verifying default (30s) and custom (300s) TTL behavior

Fixes #120

Motivation

The hardcoded 30-second lock TTL combined with the probabilistic refresh mechanism (10% chance per 250ms iteration) creates a ~0.18% failure rate per lock operation when using TTL-based stores like RedisStore. This causes sporadic LockConflictedException — the lock expires before being refreshed.

Increasing the TTL (e.g. to 300s) makes the failure probability effectively zero while keeping the same refresh semantics. File-based stores (FlockStore) are unaffected since their locks don't expire.

Changes

src/Event.php:

  • New property: private int $lockTtl = 30;
  • Extended signature: preventOverlapping(?object $store = null, int $lockTtl = 30)
  • createLockObject() uses $this->lockTtl instead of hardcoded 30

tests/Unit/EventTest.php:

  • prevent_overlapping_default_lock_ttl_is_30() — verifies backward compatibility
  • prevent_overlapping_accepts_custom_lock_ttl() — verifies custom TTL (300s)

Test plan

  • Existing tests pass (phpunit --filter EventTest → 50 tests, 0 failures)
  • New tests pass for default and custom TTL values
  • Manual verification with RedisStore in production (already running with equivalent patch for weeks)

Add optional `int $lockTtl` parameter to `preventOverlapping()` with a
default of 30 seconds (preserving backward compatibility). The value is
stored in a new `$lockTtl` property and used in `createLockObject()`
instead of the previously hardcoded `$ttl = 30`.

This allows users of TTL-based lock stores (e.g. RedisStore) to set a
longer TTL, avoiding sporadic `LockConflictedException` caused by the
probabilistic refresh mechanism not being able to reliably refresh a
30-second lock in time.
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.

preventOverlapping() lock TTL should be configurable — hardcoded 30s causes sporadic LockConflictedException with Redis

1 participant

Comments