GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — test: fix race condition in unrefd interval test by mcornac · Pull Request #3550 · nodejs/node

Conversation

@mcornac

@mcornac mcornac commented Oct 27, 2015

Copy link
Copy Markdown
Contributor

Before this commit, test-timers-unrefd-interval-still-fire required a
1ms interval to fire 5 times before a 100ms timeout to pass which could
cause intermittent failures in CI and in issue #1781.

This commit gives the test up to 5x as long to complete while allowing
the test to complete as quickly as before when possible.
cc @mhdawson

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mcornac
test: fix race condition in unrefd interval test
54285aa
Before this commit, test-timers-unrefd-interval-still-fire required a
1ms interval to fire 5 times before a 100ms timeout to pass which could
cause intermittent failures in CI and in issue #1781.

This commit gives the test up to 5x as long to complete while allowing
the test to complete as quickly as before when possible.
@Fishrock123

Fishrock123 commented Oct 27, 2015

Copy link
Copy Markdown
Contributor

I'm not too fond of this way of doing things.

I suggest re-writing the test to be more like https://github.com/nodejs/node/blob/master/test/parallel/test-timers-unref-active-unenrolled-disposed.js

Particularly, it is more reliable to depend on the order of timer execution rather than arbitrary timeouts.

A master timeout is, however, necessary to keep the process open. That being said, the last unrefed timeout should be able to tell when it has succeed and cancel the master timeout.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Oct 27, 2015

Copy link
Copy Markdown
Contributor

i.e.

setTimeout(b, 2)
setTimeout(a, 1)

b will always be called last. You must register the longer timers first.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123 Fishrock123 added timers Issues and PRs related to timers, setImmediate(), setInterval(), and setTimeout(). test Issues and PRs related to Node.js core tests and test infrastructure. labels Oct 27, 2015
@Fishrock123

Fishrock123 commented Oct 27, 2015

Copy link
Copy Markdown
Contributor

Actually, that exact order may not be correct for "regular" timers, in my test it applied to _unrefActive, which is... a little different. I'll look more in detail soon.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Oct 28, 2015

Copy link
Copy Markdown
Contributor Author

I made some changes to look more like https://github.com/nodejs/node/blob/master/test/parallel/test-timers-unref-active-unenrolled-disposed.js. Mainly so that the master timeout is cleared as soon as the last unrefd interval fires.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123 Fishrock123 self-assigned this Oct 28, 2015
Fishrock123
Fishrock123 reviewed Oct 28, 2015
View reviewed changes
Comment thread test/parallel/test-timers-unrefd-interval-still-fires.js Outdated

@Fishrock123 Fishrock123 Oct 28, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

500 seems awfuly large with scaling.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mcornac mcornac Oct 28, 2015

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

What number is reasonable here?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Oct 28, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

100, although really you could probably get away with something smaller. If this is taking more than 50 or so ms you've got some big issues.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mcornac mcornac Oct 28, 2015

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

It seems like 100ms was causing the intermittent failure in CI in the first place, unless that can be handled in platformTimeout.
cc @mhdawson

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Oct 28, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Hmmm, looks like we didn't do that for AIX yet? https://github.com/nodejs/node/blob/master/test/common.js#L232-L240

In this case I suggest setting the timeout to 500 only if common.isAix is true.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Fishrock123

Fishrock123 commented Oct 28, 2015

Copy link
Copy Markdown
Contributor

@mhdawson what are the sort of specs of an AIX machine? I am highly curious how 5 1ms timers could take more than 100ms.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mhdawson

mhdawson commented Oct 30, 2015

Copy link
Copy Markdown
Member

I think I may have gotten it wrong and its zLinux. as opposed to AIX. I think the main issue is that we have a good number of VMs sharing the same hardware. Its not that it fails all the time only that we see intermittent failures. @thinkingdust can you talk to Joran and provide more details if you have them.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mhdawson

mhdawson commented Oct 30, 2015

Copy link
Copy Markdown
Member

In terms of platform timeout I don't want to extend the length of all AIX tests because we see intermittent failures on a few tests.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Nov 2, 2015

Copy link
Copy Markdown
Contributor Author

The original failure was on zLinux so a platform specific change won't do.
With the updates, the test now clears the master timeout on success so its length will only matter when deciding that the test has failed.
I don't think the failure has repeated so I think we could keep the original 100ms.
/cc @joransiu

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jasnell jasnell added the lts-watch-v4.x label Nov 3, 2015
@Fishrock123

Fishrock123 commented Nov 4, 2015

Copy link
Copy Markdown
Contributor

LGTM if common.platformTimeout(500); is 100 then.

I'd really like to know if @joransiu or anyone else has any insight as to how that could be happening though.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Nov 4, 2015

Copy link
Copy Markdown
Contributor Author

I think the failure was caused by other processes running on the CI machine. I can replicate the failure with the bash script below. The failure rate can be controlled by changing the number of background processes.

#!/bin/bash

NUM_PROCESSES=32
for j in `seq 1 $NUM_PROCESSES`;
do
  k=0
  while [ $k -lt 1000000 ]
  do
    ((k++))
  done &
done

pass=0
fail=0
output=""
for i in `seq 1 100`;
do
  output=$(./node test/parallel/test-timers-unrefd-interval-still-fires.js 2>&1)
  len=${#output}
  if [ $len -eq 0 ]; then
    ((pass++))
  else
    ((fail++))
  fi
  if [ $i -ne 1 ]; then
    echo -en "\e[1A"
  fi
  echo pass $pass : fail $fail
done
wait
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 4, 2015

Copy link
Copy Markdown
Contributor

@thinkingdust Any idea how many processor-level threads that machine has?

Like, are you literally just clogging everything up that much that the timer doesn't get run?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@joransiu

joransiu commented Nov 4, 2015

Copy link
Copy Markdown
Contributor

I had suggested a few experiments with @thinkingdust to get a better gauge on various timeout values for our Linux on Z configuration. The machine we are running on is a guest Linux system running with 8 CPs on zEC12 @ 5.5GHz => 8 processor level threads available.

With relative little load on the system, our very informal measurements:

Timeout Failure Rate
20ms 16/500 (~3%)
30ms 4 / 500 (~1%)
100ms 0 / 500 (0%)

Now, if we ran 8 instances in parallel... @ 100ms timeout, we observe a failure rate of about 1%. I'd say given these stats, 100ms is probably reasonable.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Nov 4, 2015

Copy link
Copy Markdown
Contributor Author

Keep open timeout has been changed back to 100ms.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fishrock123
Fishrock123 reviewed Nov 9, 2015
View reviewed changes
Comment thread test/parallel/test-timers-unrefd-interval-still-fires.js Outdated

@Fishrock123 Fishrock123 Nov 9, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

It's probably more informative to just throw like https://github.com/nodejs/node/blob/master/test/parallel/test-timers-unref-active-unenrolled-disposed.js#L14

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Fishrock123

Fishrock123 commented Nov 9, 2015

Copy link
Copy Markdown
Contributor

8 CPs on zEC12 @ 5.5GHz => 8 processor level threads available.

That should never fail this.

Is it possible libuv isn't scheduling these efficiently on AIX?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 9, 2015

Copy link
Copy Markdown
Contributor

LGTM minus the comment.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Nov 9, 2015

Copy link
Copy Markdown
Contributor Author

I made the change to throw the same error as https://github.com/nodejs/node/blob/master/test/parallel/test-timers-unref-active-unenrolled-disposed.js#L14

I think it was slightly useful to print nbIntervalFired to see if the interval callback ran at all. Is it a good idea to include that?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 9, 2015

Copy link
Copy Markdown
Contributor

@thinkingdust sure.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mcornac

mcornac commented Nov 9, 2015

Copy link
Copy Markdown
Contributor Author

@Fishrock123 Is this format okay?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 9, 2015

Copy link
Copy Markdown
Contributor

Was going to land squashed as

    test: fix race condition in unrefd interval test

    The test now relies more on timers implementation rather than arbitrary
    timeouts, and will cancel a master timeout once complete.

    Refs: https://github.com/nodejs/node/issues/1781
    PR-URL: https://github.com/nodejs/node/pull/3550
    Reviewed-By: Michael Dawson <[email protected]>
    Reviewed-By: Jeremiah Senkpiel <[email protected]>

@thinkingdust But I think I actually missed something, sorry, we should harden the test a bit more.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fishrock123
Fishrock123 reviewed Nov 9, 2015
View reviewed changes
Comment thread test/parallel/test-timers-unrefd-interval-still-fires.js Outdated

@Fishrock123 Fishrock123 Nov 9, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

In here, can you set timer._onTimeout to a function that throws an error if it called again?

(That will ensure it does not get called more than 5 times.)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mcornac
test: clear timeout on last unrefd interval fire
06d1980
@mcornac

mcornac commented Nov 16, 2015

Copy link
Copy Markdown
Contributor Author

@Fishrock123 Any more suggestions for this PR?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 19, 2015

Copy link
Copy Markdown
Contributor

CI: https://ci.nodejs.org/job/node-test-pull-request/789/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fishrock123 pushed a commit to Fishrock123/node that referenced this pull request Nov 20, 2015
@mcornac @Fishrock123
test: fix race condition in unrefd interval test
6de82c6
Rely more on timers implementation rather than arbitrary timeouts.

Refs: nodejs#1781
PR-URL: nodejs#3550

Reviewed-By: Jeremiah Senkpiel <[email protected]>
@Fishrock123

Fishrock123 commented Nov 20, 2015

Copy link
Copy Markdown
Contributor

Thanks, landed in 6de82c6

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123 Fishrock123 closed this Nov 20, 2015
@Fishrock123

Fishrock123 commented Nov 20, 2015

Copy link
Copy Markdown
Contributor

(Squashed and updated description)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@misterdjules

misterdjules commented Nov 20, 2015

Copy link
Copy Markdown

I don't think I understand why 6de82c6 would fix the race condition and make the test fail less often in the situation described in the first comment of this PR. Am I missing something?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 20, 2015

Copy link
Copy Markdown
Contributor

Ugh, guess I should have updated the description.

It doesn't fix it per se, but it does refactor the test to work in a more reliable fashion.

Ultimately if your 5 1ms timers aren't firing in under like 25ms you've probably got serious hardware problems, or armv6.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@misterdjules

misterdjules commented Nov 20, 2015

Copy link
Copy Markdown

One way to fix the flakiness of this test would be to rely on the tests suite's per-test timeout (which is currently set to 60 seconds) and instead of adding a timer to hold the loop open (which would require us to hardcode this 60 seconds tests suite timeout somewhere else, or refactor the tests suite driver so that it can communicate that value to JS tests), we could add another type of handle that holds the loop open indefinitely, like a net.Server instance.

When the fifth timer's callback is called, we can close that handle and the test would exist asap in most cases, or the tests suite would make it time out in case it would fail. But we would get rid of almost all false positives.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123

Fishrock123 commented Nov 20, 2015

Copy link
Copy Markdown
Contributor

When the fifth timer's callback is called, we can close that handle and the test would exist asap in most cases, or the tests suite would make it time out in case it would fail.

That's what happens now.

If 5 1ms timers fail within <100ms there are issues, this isn't just flakiness.

As it stands, this patch appears to have corrected the original issue.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@misterdjules

misterdjules commented Nov 20, 2015

Copy link
Copy Markdown

When the fifth timer's callback is called, we can close that handle and the test would exist asap in most cases, or the tests suite would make it time out in case it would fail.

That's what happens now.

It seems that what happens now is that the test will fail if the 5 timers' callbacks haven't run within 100 ms. According to @mhdawson and @joransiu it is possible that on systems with high load, 5 timers' callbacks take longer than 100ms to run, which seems entirely plausible. That doesn't mean that unrefed timers are broken, but still it seems that this change would make the test fail in these situations. That would make the test flaky.

What I was describing is a way to give much more time for these timers to fire, not just 100ms, without making the best cases take longer, and without hardcoding the expiry delay for the handle that keeps the loop open. I believe that would make the test non flaky.

As it stands, this patch appears to have corrected the original issue.

Do you mean that it fixes #1781, or that it fixes the problems reported by @mhdawson, or both?

If I'm not missing anything, 6de82c6 has been pushed today, and #1781 was closed on July 28th, so I don't know how we can determine that this change fixed that issue.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Fishrock123 Fishrock123 mentioned this pull request Nov 26, 2015
deps: upgrade npm to 3.5.0 #4032
Closed
rvagg pushed a commit that referenced this pull request Dec 5, 2015
@mcornac @rvagg
test: fix race condition in unrefd interval test
788541b
Rely more on timers implementation rather than arbitrary timeouts.

Refs: #1781
PR-URL: #3550

Reviewed-By: Jeremiah Senkpiel <[email protected]>
This was referenced Dec 8, 2015
Release proposal: v5.2.0 #4180
Closed
Release proposal: v5.2.0 (Stable) #4181
Merged
@rvagg rvagg mentioned this pull request Dec 17, 2015
Release 4.2.4 Planning #4321
Closed
MylesBorins pushed a commit that referenced this pull request Dec 29, 2015
@mcornac Myles Borins
test: fix race condition in unrefd interval test
15ae55e
Rely more on timers implementation rather than arbitrary timeouts.

Refs: #1781
PR-URL: #3550

Reviewed-By: Jeremiah Senkpiel <[email protected]>
@MylesBorins MylesBorins added land-on-v4.x and removed lts-watch-v4.x labels Dec 29, 2015
This was referenced Jan 7, 2016
test: fix test-timers-unrefd-interval-still-fires #4561
Closed
test: test-timers-unrefd-interval-still-fires.js flaky on smartOS #4559
Closed
MylesBorins pushed a commit that referenced this pull request Jan 19, 2016
@mcornac Myles Borins
test: fix race condition in unrefd interval test
166523d
Rely more on timers implementation rather than arbitrary timeouts.

Refs: #1781
PR-URL: #3550

Reviewed-By: Jeremiah Senkpiel <[email protected]>
@MylesBorins MylesBorins mentioned this pull request Jan 19, 2016
V4.2.5 proposal #4768
Merged
@B020239 B020239 mentioned this pull request Mar 9, 2024
[Snyk] Upgrade esbuild from 0.19.5 to 0.20.0 B020239/node#1
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@Fishrock123 Fishrock123

Labels

test Issues and PRs related to Node.js core tests and test infrastructure. timers Issues and PRs related to timers, setImmediate(), setInterval(), and setTimeout().

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@mcornac @Fishrock123 @mhdawson @joransiu @misterdjules @jasnell @MylesBorins
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.