Skip to content

Fix valkey-benchmark hanging in single-thread duration mode#3079

Merged
zuiderkwast merged 2 commits into
valkey-io:unstablefrom
yzc-yzc:fix-benchmark-duration-hang
Jan 20, 2026
Merged

Fix valkey-benchmark hanging in single-thread duration mode#3079
zuiderkwast merged 2 commits into
valkey-io:unstablefrom
yzc-yzc:fix-benchmark-duration-hang

Conversation

@yzc-yzc

@yzc-yzc yzc-yzc commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

In single-thread mode with --duration, the benchmark could hang indefinitely after the duration elapsed.

Root Cause

Consider the following scenario:

Step 1 (T = 0.99s, duration = 1s):

  • readHandler receives response, calls clientDone()
  • isBenchmarkFinished() returns false (0.99s < 1s)
  • clientDone() calls resetClient()

Step 2 (T = 1.01s):

  • writeHandler is called
  • isBenchmarkFinished() returns true (1.01s >= 1s)
  • writeHandler returns early, no request sent, no read event registered

Result:

  • readHandler never triggers → clientDone() never called → no aeStop()
  • showThroughput() checks num_threads && isBenchmarkFinished(), skipping single-thread mode
  • Event loop never terminates

Fixes #2893, fixes #2843

Signed-off-by: yzc-yzc <96833212+yzc-yzc@users.noreply.github.com>
@yzc-yzc

yzc-yzc commented Jan 20, 2026

Copy link
Copy Markdown
Contributor Author

One way to reliably trigger this bug is to add the following code in writeHandler() before the isBenchmarkFinished() check:

/* Initialize request when nothing was written. */
if (c->written == 0) {
    // DEBUG: Force duration to expire
    static bool flag = true;
    if (flag) {
        config.start -= 1000;  // Simulate 1 second has passed
        flag = false;
    }
    
    int requests_issued = atomic_fetch_add_explicit(...);
    if (isBenchmarkFinished(requests_issued)) {
        c->pending = 0; 
        return;
    }
    ...
}

Then test with --duration 1.

@codecov

codecov Bot commented Jan 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.30%. Comparing base (0b1f99d) to head (b1a43af).
⚠️ Report is 2 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #3079      +/-   ##
============================================
- Coverage     74.33%   74.30%   -0.04%     
============================================
  Files           129      129              
  Lines         71009    71009              
============================================
- Hits          52784    52762      -22     
- Misses        18225    18247      +22     
Files with missing lines Coverage Δ
src/valkey-benchmark.c 61.50% <100.00%> (ø)

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yzc-yzc yzc-yzc marked this pull request as draft January 20, 2026 09:23
Signed-off-by: yzc-yzc <96833212+yzc-yzc@users.noreply.github.com>
@yzc-yzc yzc-yzc marked this pull request as ready for review January 20, 2026 13:51

@zuiderkwast zuiderkwast left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks.

@rainsupreme PTAL.

@dvkashapov dvkashapov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@sarthakaggarwal97 sarthakaggarwal97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you! This will help daily CI run green.

@zuiderkwast zuiderkwast merged commit 8fdc9e6 into valkey-io:unstable Jan 20, 2026
24 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to To be backported in Valkey 9.0 Jan 20, 2026

@rainsupreme rainsupreme left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

haha wow I didn't see that earlier! good catch 👍

arshidkv12 pushed a commit to arshidkv12/valkey that referenced this pull request Jan 23, 2026
…o#3079)

In single-thread mode with --duration, the benchmark could hang
indefinitely after the duration elapsed.

## Root Cause
Consider the following scenario:

**Step 1** (T = 0.99s, duration = 1s):
- `readHandler` receives response, calls `clientDone()`
- `isBenchmarkFinished()` returns `false` (0.99s < 1s)
- `clientDone()` calls `resetClient()`

**Step 2** (T = 1.01s):
- `writeHandler` is called
- `isBenchmarkFinished()` returns `true` (1.01s >= 1s)
- `writeHandler` returns early, **no request sent, no read event
registered**

**Result**:
- `readHandler` never triggers → `clientDone()` never called → no
`aeStop()`
- `showThroughput()` checks `num_threads && isBenchmarkFinished()`,
skipping single-thread mode
- **Event loop never terminates**

Fixes valkey-io#2893, fixes valkey-io#2843

---------

Signed-off-by: yzc-yzc <96833212+yzc-yzc@users.noreply.github.com>
Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
@zuiderkwast zuiderkwast removed this from Valkey 9.0 Jan 29, 2026
@zuiderkwast

Copy link
Copy Markdown
Contributor

#2581 was not included in 9.0 so we should not backport this fix.

harrylin98 pushed a commit to harrylin98/valkey_forked that referenced this pull request Feb 19, 2026
…o#3079)

In single-thread mode with --duration, the benchmark could hang
indefinitely after the duration elapsed.

## Root Cause
Consider the following scenario: 

**Step 1** (T = 0.99s, duration = 1s):
- `readHandler` receives response, calls `clientDone()`
- `isBenchmarkFinished()` returns `false` (0.99s < 1s)
- `clientDone()` calls `resetClient()`

**Step 2** (T = 1.01s):
- `writeHandler` is called
- `isBenchmarkFinished()` returns `true` (1.01s >= 1s)
- `writeHandler` returns early, **no request sent, no read event
registered**

**Result**:
- `readHandler` never triggers → `clientDone()` never called → no
`aeStop()`
- `showThroughput()` checks `num_threads && isBenchmarkFinished()`,
skipping single-thread mode
- **Event loop never terminates**

Fixes valkey-io#2893, fixes valkey-io#2843

---------

Signed-off-by: yzc-yzc <96833212+yzc-yzc@users.noreply.github.com>
hpatro pushed a commit to hpatro/valkey that referenced this pull request Mar 5, 2026
…o#3079)

In single-thread mode with --duration, the benchmark could hang
indefinitely after the duration elapsed.

## Root Cause
Consider the following scenario:

**Step 1** (T = 0.99s, duration = 1s):
- `readHandler` receives response, calls `clientDone()`
- `isBenchmarkFinished()` returns `false` (0.99s < 1s)
- `clientDone()` calls `resetClient()`

**Step 2** (T = 1.01s):
- `writeHandler` is called
- `isBenchmarkFinished()` returns `true` (1.01s >= 1s)
- `writeHandler` returns early, **no request sent, no read event
registered**

**Result**:
- `readHandler` never triggers → `clientDone()` never called → no
`aeStop()`
- `showThroughput()` checks `num_threads && isBenchmarkFinished()`,
skipping single-thread mode
- **Event loop never terminates**

Fixes valkey-io#2893, fixes valkey-io#2843

---------

Signed-off-by: yzc-yzc <96833212+yzc-yzc@users.noreply.github.com>
Signed-off-by: Harkrishn Patro <bunty.hari@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

5 participants