Skip to content

Conversation

@masenf
Copy link
Collaborator

@masenf masenf commented Nov 13, 2025

Make the oplock hold time configurable and drop the default down to 50% of the configured lock timeout to avoid lock expiration between the lease breaker sleep ending and the coroutine actually getting scheduled for execution.

Make the oplock hold time configurable and drop the default down to 50% of the
configured lock timeout to avoid lock expiration between the lease breaker
sleep ending and the coroutine actually getting scheduled for execution.
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 13, 2025

CodSpeed Performance Report

Merging #5975 will not alter performance

Comparing masenf/config-oplock-time (f439e07) with main (da53877)

Summary

✅ 8 untouched

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 13, 2025

Greptile Overview

Greptile Summary

This PR makes the opportunistic lock hold time configurable via the REFLEX_OPLOCK_HOLD_TIME_MS environment variable and changes the default from 80% to 50% of the lock expiration time to prevent lock expiration issues.

Key changes:

  • Added REFLEX_OPLOCK_HOLD_TIME_MS environment variable (defaults to 0, which triggers 50% calculation)
  • Introduced _default_oplock_hold_time_ms() function with fallback to lock_expiration // 2
  • Added oplock_hold_time_ms field to StateManagerRedis class
  • Replaced hardcoded self.lock_expiration * 0.8 calculation with configurable self.oplock_hold_time_ms
  • Added validation ensuring oplock hold time is less than lock expiration time

The change addresses a race condition where the previous 80% threshold could cause locks to expire between the lease breaker sleep ending and coroutine execution.

Confidence Score: 4/5

  • This PR is safe to merge with minor style improvement suggested
  • The implementation correctly makes the oplock hold time configurable and changes the default from 80% to 50% of lock expiration. The validation logic properly ensures the hold time is less than lock expiration. Only suggestion is to add a clarifying comment per project style guidelines for time-based calculations
  • No files require special attention - all changes are straightforward configuration additions

Important Files Changed

File Analysis

Filename Score Overview
reflex/environment.py 5/5 Added REFLEX_OPLOCK_HOLD_TIME_MS environment variable with default value 0, properly typed as int and following naming conventions
reflex/istate/manager/redis.py 4/5 Added configurable oplock hold time with proper validation and default calculation (50% of lock expiration); replaced hardcoded 0.8 multiplier with new configurable value

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Env as Environment Variables
    participant SMR as StateManagerRedis
    participant Lock as Redis Lock
    participant LB as Lease Breaker

    App->>Env: Read REFLEX_OPLOCK_HOLD_TIME_MS
    Env-->>App: Return configured value or 0
    
    App->>SMR: Initialize StateManagerRedis
    SMR->>SMR: Call _default_oplock_hold_time_ms()
    alt REFLEX_OPLOCK_HOLD_TIME_MS set
        SMR->>SMR: Use configured value
    else REFLEX_OPLOCK_HOLD_TIME_MS is 0
        SMR->>SMR: Calculate lock_expiration // 2
        Note over SMR: Default: 50% of lock expiration<br/>(e.g., 5000ms for 10000ms)
    end
    
    SMR->>SMR: Validate oplock_hold_time_ms < lock_expiration
    alt Validation fails
        SMR-->>App: Raise InvalidLockWarningThresholdError
    end
    
    App->>SMR: Acquire opportunistic lock
    SMR->>Lock: Acquire Redis lock
    Lock-->>SMR: Lock acquired
    
    SMR->>LB: Start lease_breaker task
    LB->>LB: Calculate lease_break_time<br/>= oplock_hold_time_ms / 1000
    Note over LB: Previously: lock_expiration * 0.8 / 1000<br/>Now: configurable oplock_hold_time_ms / 1000
    LB->>LB: Sleep for lease_break_time seconds
    
    LB->>Lock: Release lock after sleep
    Lock-->>LB: Lock released
    LB-->>SMR: Lease breaker completed
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +59 to +61
return environment.REFLEX_OPLOCK_HOLD_TIME_MS.get() or (
_default_lock_expiration() // 2
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Add a comment explaining the time calculation in human-readable terms, e.g., "# Default to 50% of lock expiration (e.g., 5000ms for 10000ms expiration)"

Suggested change
return environment.REFLEX_OPLOCK_HOLD_TIME_MS.get() or (
_default_lock_expiration() // 2
)
return environment.REFLEX_OPLOCK_HOLD_TIME_MS.get() or (
_default_lock_expiration() // 2 # Default to 50% of lock expiration (e.g., 5000ms for 10000ms expiration)
)

Context Used: Rule from dashboard - When using time-based calculations in code, include comments that explain the time duration in human... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: reflex/istate/manager/redis.py
Line: 59:61

Comment:
**style:** Add a comment explaining the time calculation in human-readable terms, e.g., "# Default to 50% of lock expiration (e.g., 5000ms for 10000ms expiration)"

```suggestion
    return environment.REFLEX_OPLOCK_HOLD_TIME_MS.get() or (
        _default_lock_expiration() // 2  # Default to 50% of lock expiration (e.g., 5000ms for 10000ms expiration)
    )
```

**Context Used:** Rule from `dashboard` - When using time-based calculations in code, include comments that explain the time duration in human... ([source](https://app.greptile.com/review/custom-context?memory=f12765cb-0537-4be8-81ad-061314e0e5d0))

How can I resolve this? If you propose a fix, please make it concise.

@masenf masenf merged commit a679316 into main Nov 14, 2025
47 checks passed
@masenf masenf deleted the masenf/config-oplock-time branch November 14, 2025 00:19
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.

3 participants