feat: always sync full 24 months horizon of contingents
This commit is contained in:
Generated
+20
-21
@@ -3120,24 +3120,24 @@
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.1",
|
||||
"version": "2.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fd5018f6815fff903946d0564977b44ce8010e29"
|
||||
"reference": "a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29",
|
||||
"reference": "fd5018f6815fff903946d0564977b44ce8010e29",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7",
|
||||
"reference": "a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10"
|
||||
"phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -3181,9 +3181,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.1"
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.11.0"
|
||||
},
|
||||
"time": "2026-06-23T18:43:15+00:00"
|
||||
"time": "2026-08-18T06:18:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
@@ -12001,16 +12001,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.95.18",
|
||||
"version": "v3.95.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "a8b4e4216faabf67f4e96110ee99a48c96e4e683"
|
||||
"reference": "4d6c9886a77dbc1db3b9eaca6472cedf9eb1fab7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a8b4e4216faabf67f4e96110ee99a48c96e4e683",
|
||||
"reference": "a8b4e4216faabf67f4e96110ee99a48c96e4e683",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4d6c9886a77dbc1db3b9eaca6472cedf9eb1fab7",
|
||||
"reference": "4d6c9886a77dbc1db3b9eaca6472cedf9eb1fab7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -12046,7 +12046,6 @@
|
||||
"infection/infection": "^0.32.7",
|
||||
"justinrainbow/json-schema": "^6.10.0",
|
||||
"keradus/cli-executor": "^2.3",
|
||||
"mikey179/vfsstream": "^1.6.12",
|
||||
"php-coveralls/php-coveralls": "^2.9.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8",
|
||||
@@ -12094,7 +12093,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.18"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.20"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -12102,7 +12101,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-07-30T15:46:02+00:00"
|
||||
"time": "2026-08-19T16:28:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
@@ -13496,16 +13495,16 @@
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "2.6.2",
|
||||
"version": "2.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rectorphp/rector.git",
|
||||
"reference": "03cd615cdd5648abb5f10ff3a684fdb976687190"
|
||||
"reference": "7e46709996a4b3dc59e1d6ecbb6a38ace335bd58"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/03cd615cdd5648abb5f10ff3a684fdb976687190",
|
||||
"reference": "03cd615cdd5648abb5f10ff3a684fdb976687190",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/7e46709996a4b3dc59e1d6ecbb6a38ace335bd58",
|
||||
"reference": "7e46709996a4b3dc59e1d6ecbb6a38ace335bd58",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -13544,7 +13543,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rectorphp/rector/issues",
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.6.2"
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.6.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -13552,7 +13551,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-08-12T06:23:05+00:00"
|
||||
"time": "2026-08-18T22:01:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
||||
@@ -59,14 +59,10 @@ when@prod:
|
||||
frequency: "0 20-23,0-7 * * *"
|
||||
description: "Syncs BusPro XML data hourly outside peak hours"
|
||||
|
||||
- task: app:bpn:sync-contingents --horizon-months=3
|
||||
frequency: "*/15 8-19 * * *"
|
||||
description: "Syncs near-term contingent snapshots every 15 min. during peak hours"
|
||||
- task: app:bpn:sync-contingents
|
||||
frequency: "5-59/15 8-19 * * *"
|
||||
description: "Syncs the full contingent horizon every 15 min. during peak hours"
|
||||
|
||||
- task: app:bpn:sync-contingents --horizon-months=3
|
||||
- task: app:bpn:sync-contingents
|
||||
frequency: "5 20-23,0-7 * * *"
|
||||
description: "Syncs near-term contingent snapshots hourly outside peak hours"
|
||||
|
||||
- task: app:bpn:sync-contingents --horizon-months=24
|
||||
frequency: "40 2,13 * * *"
|
||||
description: "Syncs the full contingent horizon twice daily"
|
||||
description: "Syncs the full contingent horizon hourly outside peak hours"
|
||||
|
||||
@@ -26,7 +26,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
/**
|
||||
* Console entrypoint for the scheduled contingent snapshot sync.
|
||||
*
|
||||
* Runs at two cadences: a short horizon frequently, the full horizon a couple of times a day.
|
||||
* Scheduled over the full horizon throughout: every 15 minutes during peak hours, hourly
|
||||
* outside them. The options exist for ad-hoc runs — a narrower --horizon-months, or --hotel
|
||||
* to re-sync a single accommodation while debugging.
|
||||
*/
|
||||
class BpnSyncContingentsCommand extends Command
|
||||
{
|
||||
@@ -48,7 +50,7 @@ class BpnSyncContingentsCommand extends Command
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->addOption('horizon-months', null, InputOption::VALUE_REQUIRED, 'How many months ahead to sync', '24')
|
||||
->addOption('horizon-months', null, InputOption::VALUE_REQUIRED, 'How many months ahead to sync (defaults to the full horizon)', '24')
|
||||
->addOption('hotel', null, InputOption::VALUE_REQUIRED, 'Restrict the run to a single calendarCode')
|
||||
->addOption('stale-after', null, InputOption::VALUE_REQUIRED, 'Minimum minutes since the last sync before an accommodation is eligible (ignored with --force)', '0')
|
||||
->addOption('force', 'f', InputOption::VALUE_NONE, 'Sync even if the snapshot was refreshed recently')
|
||||
@@ -148,10 +150,10 @@ class BpnSyncContingentsCommand extends Command
|
||||
|
||||
// Only a *total* failure is worth failing the task over: that means upstream is down or
|
||||
// the API key is rejected, and the scheduler's failure mail is genuinely actionable.
|
||||
// A single hotel breaking must stay quiet — this task runs every 15 minutes, so failing
|
||||
// on it would mail dozens of times a day until someone silenced the task. That hotel is
|
||||
// not lost track of: its own calendar serves a 502, and contingent_sync_state records
|
||||
// failure_count and last_error.
|
||||
// A single hotel breaking must stay quiet — this task runs every 15 minutes during the
|
||||
// day, so failing on it would mail dozens of times a day until someone silenced the task.
|
||||
// That hotel is not lost track of: its own calendar serves a 502, and
|
||||
// contingent_sync_state records failure_count and last_error.
|
||||
return $processed > 0 && $failed === $processed ? Command::FAILURE : Command::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,9 @@ class ContingentSyncState
|
||||
/**
|
||||
* Records a successful sync of a window ending at $horizonTo.
|
||||
*
|
||||
* The horizon only ever grows: the near-term job runs far more often than the full-horizon
|
||||
* one, and must not discard the reach the latter established.
|
||||
* The horizon only ever grows, so an ad-hoc run over a narrow window — say
|
||||
* `--horizon-months=1` while debugging — cannot discard the reach the scheduled full sync
|
||||
* established.
|
||||
*/
|
||||
public function recordSuccess(\DateTimeImmutable $syncedAt, \DateTimeImmutable $horizonTo): self
|
||||
{
|
||||
|
||||
@@ -37,8 +37,8 @@ class ContingentSnapshotManager
|
||||
* Refreshes [dateFrom, dateTo] for a single accommodation.
|
||||
*
|
||||
* Days are fetched, diffed against what is stored and then persisted; the snapshot outside
|
||||
* the requested window is left untouched, which is what lets the near-term and full-horizon
|
||||
* schedules run at different cadences without fighting each other.
|
||||
* the requested window is left untouched, so a narrow ad-hoc run cannot truncate what a
|
||||
* full-horizon run already stored.
|
||||
*/
|
||||
public function sync(
|
||||
Accommodation $accommodation,
|
||||
|
||||
@@ -24,8 +24,9 @@ class ContingentSnapshotReader
|
||||
/**
|
||||
* How old the snapshot may get before we stop presenting it as current availability.
|
||||
*
|
||||
* The near-term sync runs every 15 minutes during the day and hourly overnight, so this only
|
||||
* trips when the scheduler is genuinely broken, never on the normal cadence.
|
||||
* The sync runs every 15 minutes during the day and hourly overnight, so even the sparsest
|
||||
* cadence leaves five missed runs of slack: this only trips when the scheduler is genuinely
|
||||
* broken, never on the normal cadence.
|
||||
*/
|
||||
private const string MAX_SNAPSHOT_AGE = '-6 hours';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user