Skip to content

Commit 8584592

Browse files
committed
Revert "Block workflow traffic until bootstrap blockers clear"
This reverts commit d4622f4.
1 parent d4622f4 commit 8584592

6 files changed

Lines changed: 3 additions & 260 deletions

File tree

‎README.md‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -705,12 +705,6 @@ of pretending to be interchangeable HTTP peers. `GET /api/cluster/info`,
705705
`/api/health`, and `/api/ready` stay available for discovery and liveness even
706706
on scheduler-only, execution-only, or matching-only nodes.
707707

708-
Those runtime-serving workflow routes also fail closed on bootstrap blockers.
709-
If database connectivity or workflow-table migrations are not ready, hosted
710-
workflow and worker-protocol routes return `503` with
711-
`reason: "workflow_v2_blocked"` plus `blocked_by` and `remediation` instead of
712-
accepting traffic that depends on an incomplete rollout state.
713-
714708
The same `GET /api/cluster/info` response now includes a versioned
715709
`coordination_health` manifest for rollout-safety coordination risk. It
716710
summarizes the current server-wide workflow v2 health status, warning and error

‎app/Http/Middleware/RequireWorkflowBootstrapReady.php‎

Lines changed: 0 additions & 59 deletions
This file was deleted.

‎app/Support/RemoteScheduleStarter.php‎

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ final class RemoteScheduleStarter implements ScheduleWorkflowStarter
1616
{
1717
public function __construct(
1818
private readonly WorkflowStartService $startService,
19-
private readonly ServerReadiness $readiness,
2019
) {}
2120

2221
public function start(
@@ -25,20 +24,6 @@ public function start(
2524
string $outcome,
2625
?string $effectiveOverlapPolicy = null,
2726
): ScheduleStartResult {
28-
$workflowStatus = $this->readiness->workflowStatus();
29-
$blockedBy = is_array($workflowStatus['blocked_by'] ?? null)
30-
? array_values(array_filter($workflowStatus['blocked_by'], static fn (mixed $value): bool => is_string($value) && $value !== ''))
31-
: [];
32-
33-
if (($workflowStatus['status'] ?? null) === 'blocked' && $blockedBy !== []) {
34-
throw new WorkflowExecutionUnavailableException(
35-
'schedule_start',
36-
$schedule->schedule_id,
37-
'workflow_v2_blocked',
38-
'Workflow v2 bootstrap blockers must clear before scheduled workflows can start.',
39-
);
40-
}
41-
4227
$action = WorkflowSchedule::normalizeActionTimeouts(
4328
is_array($schedule->action) ? $schedule->action : [],
4429
);

‎routes/api.php‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use App\Http\Middleware\ControlPlaneVersionResolver;
1919
use App\Http\Middleware\NamespaceResolver;
2020
use App\Http\Middleware\RequireRole;
21-
use App\Http\Middleware\RequireWorkflowBootstrapReady;
2221
use App\Http\Middleware\RequireTopologyRoles;
2322
use App\Http\Middleware\WorkerProtocolVersionResolver;
2423
use Illuminate\Support\Facades\Route;
@@ -52,11 +51,6 @@
5251
// NamespaceResolver on hosted routes so wrong-node requests fail closed with a
5352
// machine-readable topology reason without leaking namespace existence.
5453
//
55-
// RequireWorkflowBootstrapReady sits in the same slot for runtime-serving
56-
// workflow routes. It only blocks on explicit database/migration bootstrap
57-
// blockers so routes fail closed during rollout/schema drift without locking
58-
// out recovery paths such as compatible worker registration.
59-
//
6054
// WorkerProtocolVersionResolver follows the same ordering for worker-plane
6155
// routes, keeping protocol skew and namespace errors in the worker envelope.
6256
Route::middleware([Authenticate::class])->group(function () {
@@ -68,7 +62,6 @@
6862
$cpv = ControlPlaneVersionResolver::class;
6963
$httpControl = RequireTopologyRoles::class.':api_ingress,control_plane';
7064
$httpWorker = RequireTopologyRoles::class.':api_ingress,control_plane';
71-
$workflowBootstrap = RequireWorkflowBootstrapReady::class;
7265
$wpv = WorkerProtocolVersionResolver::class;
7366

7467
// ── System ───────────────────────────────────────────────────────
@@ -89,7 +82,7 @@
8982
});
9083

9184
// ── Workflows ────────────────────────────────────────────────────
92-
Route::prefix('workflows')->middleware([$operator, $cpv, $httpControl, $workflowBootstrap, $ns])->group(function () {
85+
Route::prefix('workflows')->middleware([$operator, $cpv, $httpControl, $ns])->group(function () {
9386
Route::get('/', [WorkflowController::class, 'index']);
9487
Route::post('/', [WorkflowController::class, 'start']);
9588
Route::get('/{workflowId}', [WorkflowController::class, 'show']);
@@ -120,12 +113,12 @@
120113
});
121114

122115
// ── Bridge Adapters ──────────────────────────────────────────────
123-
Route::prefix('bridge-adapters')->middleware([$operator, $cpv, $httpControl, $workflowBootstrap, $ns])->group(function () {
116+
Route::prefix('bridge-adapters')->middleware([$operator, $cpv, $httpControl, $ns])->group(function () {
124117
Route::post('/webhook/{adapter}', [BridgeAdapterController::class, 'webhook']);
125118
});
126119

127120
// ── Worker Task Polling ──────────────────────────────────────────
128-
Route::prefix('worker')->middleware([$worker, $wpv, $httpWorker, $workflowBootstrap, $ns])->group(function () {
121+
Route::prefix('worker')->middleware([$worker, $wpv, $httpWorker, $ns])->group(function () {
129122
// Registration
130123
Route::post('/register', [WorkerController::class, 'register']);
131124
Route::post('/heartbeat', [WorkerController::class, 'heartbeat']);

‎tests/Feature/ScheduleEvaluateTest.php‎

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -223,34 +223,6 @@ public function test_it_records_rollout_safety_start_rejections_as_skips(): void
223223
$this->assertSame([], $schedule->recent_actions ?? []);
224224
}
225225

226-
public function test_it_skips_due_schedules_when_workflow_bootstrap_is_blocked(): void
227-
{
228-
DB::table('migrations')
229-
->where('migration', '2026_04_21_000300_add_workflow_definition_fingerprints_to_worker_registrations')
230-
->delete();
231-
232-
WorkflowSchedule::create([
233-
'schedule_id' => 'skip-bootstrap-blocked',
234-
'namespace' => 'default',
235-
'spec' => ['cron_expressions' => ['* * * * *']],
236-
'action' => ['workflow_type' => 'TestWorkflow'],
237-
'next_fire_at' => now()->subMinute(),
238-
]);
239-
240-
$this->artisan('schedule:evaluate')
241-
->assertExitCode(0)
242-
->expectsOutputToContain('skipped');
243-
244-
$schedule = WorkflowSchedule::where('schedule_id', 'skip-bootstrap-blocked')->firstOrFail();
245-
$this->assertSame('workflow_v2_blocked', $schedule->last_skip_reason);
246-
$this->assertSame(1, (int) $schedule->skipped_trigger_count);
247-
$this->assertSame(0, (int) $schedule->fires_count);
248-
$this->assertSame(0, (int) $schedule->failures_count);
249-
$this->assertNull($schedule->last_fired_at);
250-
$this->assertNull($schedule->latest_workflow_instance_id);
251-
$this->assertSame([], $schedule->recent_actions ?? []);
252-
}
253-
254226
// ── next_fire_at advancement ────────────────────────────────────
255227

256228
public function test_it_advances_next_fire_at_after_successful_fire(): void

‎tests/Feature/WorkflowBootstrapRouteGatingTest.php‎

Lines changed: 0 additions & 142 deletions
This file was deleted.

0 commit comments

Comments
 (0)