only set a new random seed if _the last_ Generator gets destruct'ed #871
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.
What is the reason for this PR?
In cases where multiple Generator instances might be created, a gc cycle collection run can trigger at any time, potentially removing "old" Generator instances, which then calls __destruct and thus seed, which reset the global mt_rand seed, impacting everyone else.
If another, still live instance of Generator gets used after that, its output is no longer deterministic, since a new random seed was set.
Generator::seed
inGenerator::__destruct
may break determinism #870 )Author's checklist
Summary of changes
I added a new static class property to
Faker\Generator
which counts the number of currently existing Generator instances: It gets incremented in __construct, and decremented in __destruct. Only if this counter reaches 0 does __destruct also callseed
to restore the system to a "properly random" state.Using a global counter is, imho, quite ugly, but since
Generator::seed
already modifies global state anyway I think its like fighting fire with fire.Other than that, I think its a quite minimal change that does not impact any other use of Faker. Cases that "properly" only ever use exactly one instance of the Generator will not see any difference in behaviour.
It's not a perfect solution by any means. But I think it is a reasonable one.
Review checklist
CHANGELOG.md