Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- `MaxJobsRebootStrategy::shouldReboot()` now requests a reload at the selected job limit, not one request later. With zero dispersion, the limit equals `requests` (#967)
- `SfxDownloader::fetch()` now also fails fast with the directory-permissions message when a cached zip artifact sits in a destination directory that is no longer writable, instead of failing late per entry inside the extraction (a read-only directory that already holds every entry still re-extracts in place); a cached archive that does not open still reaches the poisoned-artifact cleanup path (#1052)
- `StaticFilesMiddleware` now answers `HEAD` on a static file with headers only (`Content-Length`, `Content-Type`, `Accept-Ranges`, `ETag`, `Last-Modified`, `Cache-Control`, as for `GET`) and no body, and still returns 304 on a matching `If-None-Match`; methods other than `GET` and `HEAD` (`POST`, `PUT`, `DELETE`, ...) are passed to the application instead of returning the file, so the denylist and allowlist 404 answers now apply to `GET` and `HEAD` only (#903)
- The CI matrix `sed` rewrite now matches digits in package names (`[a-z0-9-]+` instead of `[a-z-]+`), so a future `symfony/foo2bar`-style package is not silently skipped by the "Update Symfony constraints" step; `GithubWorkflowsTest` now replays the rewrite character class against every `symfony/*` key in `composer.json` (#1060)
Expand Down
5 changes: 4 additions & 1 deletion src/Reboot/Strategy/MaxJobsRebootStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public function __construct(

public function shouldReboot(): bool
{
return ++$this->jobsCount > $this->maxJobs;
// shouldReboot() is consulted after each request is handled, so
// the Nth request must trigger the reload (issue #967): with `>`
// the worker served maxJobs + 1 requests before reloading.
return ++$this->jobsCount >= $this->maxJobs;
}
}
9 changes: 5 additions & 4 deletions tests/RebootStrategyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function testMaxJobsRebootStrategyReturnsFalseUntilLimit(): void

$this->assertFalse($strategy->shouldReboot());
$this->assertFalse($strategy->shouldReboot());
$this->assertFalse($strategy->shouldReboot());
// Issue #967: the 3rd request triggers the reload, not the 4th.
$this->assertTrue($strategy->shouldReboot());
}

Expand Down Expand Up @@ -60,7 +60,7 @@ public function testMaxJobsRebootStrategyWithZeroDispersion(): void
}
}

$this->assertSame(6, $rebootAt, 'Should reboot after exactly 5 jobs with 0% dispersion');
$this->assertSame(5, $rebootAt, 'Should reboot after exactly 5 jobs with 0% dispersion');
}

public function testMaxJobsRebootStrategyWithSeededRandomizer(): void
Expand All @@ -79,8 +79,9 @@ public function testMaxJobsRebootStrategyWithSeededRandomizer(): void
}
}

// With seeded randomizer, we should reboot at exactly 91 (90 + 1st job)
$this->assertSame(91, $rebootAt, 'Should reboot at deterministic job count with seeded randomizer');
// With seeded randomizer, we should reboot at exactly 90: the
// drawn limit is 90 and the 90th job triggers the reload (issue #967).
$this->assertSame(90, $rebootAt, 'Should reboot at deterministic job count with seeded randomizer');
}

public function testExceptionRebootStrategyReturnsFalseInitially(): void
Expand Down
Loading