Skip to content

Commit 22e44b8

Browse files
committed
fix(providers): restore fulfillment_final semantics for async fleet handlers
The branch had inverted ``fulfillment_final`` from True to False for EC2Fleet REQUEST/MAINTAIN, SpotFleet, ASG, and RunInstances on the theory that the create call is not "final" until the underlying instances are running. That redefinition forced all async-provider completion through the polling layer (``check_hosts_status`` → ``request_status_service.update_request_status``) and ran straight into a known limitation of that layer: any transient ``partial`` or ``failed`` poll result terminates the request irrevocably, so a healthy request that happens to be observed mid-launch flips to ``complete_with_error`` and the HostFactory wire status reports non-success despite the fleet actually being fulfilled. The semantic that actually fits the existing two-layer state machine is the one main used: ``fulfillment_final`` reports whether the provider's CREATE call is the final word from the provisioning layer. Every fleet type returns a stable resource handle synchronously on create; whether the resulting instances are running is a separate ``check_hosts_status`` concern that drives the request from IN_PROGRESS to COMPLETED on the polling layer. That keeps the provisioning path and the polling path cleanly separated and lets ``_update_request_status`` stamp COMPLETED directly when the fleet returns the full target capacity synchronously (INSTANT) or hand off to the poller when it doesn't (REQUEST / MAINTAIN / ASG / SpotFleet / RunInstances). The ``if not fulfillment_final: IN_PROGRESS`` guards in ``request_status_management_service`` stay as a safety net for any future provider that genuinely cannot signal a final CREATE-time answer (e.g. one that returns ``RequiresFollowUp``). They will not fire for any provider in the current tree.
1 parent 61584b9 commit 22e44b8

4 files changed

Lines changed: 15 additions & 13 deletions

File tree

src/orb/providers/aws/infrastructure/handlers/asg/handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def _acquire_hosts_internal(
147147
"success": True,
148148
"resource_ids": [asg_name],
149149
"instances": [], # ASG instances come later
150-
"provider_data": {"resource_type": "asg", "fulfillment_final": False},
150+
"provider_data": {"resource_type": "asg", "fulfillment_final": True},
151151
}
152152
except Exception as e:
153153
return {

src/orb/providers/aws/infrastructure/handlers/ec2_fleet/handler.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,14 @@ def _acquire_hosts_internal(
189189
"resource_type": "ec2_fleet",
190190
"fleet_type": fleet_type_value,
191191
"fleet_errors": fleet_errors,
192-
# INSTANT fleets return running instances synchronously
193-
# in the create_fleet response, so the result is the
194-
# final word. MAINTAIN / REQUEST fleets stay open and
195-
# need check_hosts_status to confirm running_count.
196-
"fulfillment_final": fleet_type is AWSFleetType.INSTANT,
192+
# ``fulfillment_final`` reports whether the provider's
193+
# CREATE call is the final word from the provisioning
194+
# layer. All fleet types return a stable fleet ID at
195+
# create time; whether instances are actually running is
196+
# a separate ``check_hosts_status`` polling concern that
197+
# drives the request from IN_PROGRESS to COMPLETED. See
198+
# ``fulfilment-model.md`` for the two-layer design.
199+
"fulfillment_final": True,
197200
"capacity_constrained": capacity_constrained,
198201
},
199202
}

src/orb/providers/aws/infrastructure/handlers/run_instances/handler.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,11 @@ def _acquire_hosts_internal(
143143
"resource_type": "run_instances",
144144
"reservation_id": resource_id,
145145
"instance_ids": instance_ids,
146-
# RunInstances returns instance IDs synchronously but
147-
# instances are still 'pending' (booting). Mark
148-
# non-final so the request stays IN_PROGRESS until
149-
# ProviderFulfilment (check_hosts_status) confirms
150-
# running_count >= target.
151-
"fulfillment_final": False,
146+
# RunInstances returns instance IDs synchronously. The
147+
# provider create-call is final; instance running-state
148+
# is driven by check_hosts_status from IN_PROGRESS to
149+
# COMPLETED on the polling layer.
150+
"fulfillment_final": True,
152151
},
153152
}
154153
except Exception as e:

src/orb/providers/aws/infrastructure/handlers/spot_fleet/handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def _acquire_hosts_internal(
145145
"resource_ids": [fleet_id],
146146
"instance_ids": [], # SpotFleet doesn't return instance IDs immediately
147147
"instances": instances,
148-
"provider_data": {"resource_type": "spot_fleet", "fulfillment_final": False},
148+
"provider_data": {"resource_type": "spot_fleet", "fulfillment_final": True},
149149
}
150150
except Exception as e:
151151
self._logger.error("SpotFleet creation failed: %s", e)

0 commit comments

Comments
 (0)