11import time
2+ import itertools
23from typing import List , Union , Optional , Dict , Literal
34from dataclasses import dataclass
45from dataclasses_json import dataclass_json
@@ -123,7 +124,12 @@ def create(self,
123124 is_spot : bool = False ,
124125 contract : Optional [Contract ] = None ,
125126 pricing : Optional [Pricing ] = None ,
126- coupon : Optional [str ] = None ) -> Instance :
127+ coupon : Optional [str ] = None ,
128+ * ,
129+ max_wait_time : float = 180 ,
130+ initial_interval : float = 0.5 ,
131+ max_interval : float = 5 ,
132+ backoff_coefficient : float = 2.0 ) -> Instance :
127133 """Creates and deploys a new cloud instance.
128134
129135 Args:
@@ -141,6 +147,10 @@ def create(self,
141147 contract: Optional contract type for the instance.
142148 pricing: Optional pricing model for the instance.
143149 coupon: Optional coupon code for discounts.
150+ max_wait_time: Maximum total wait for the instance to start provisioning, in seconds (default: 180)
151+ initial_interval: Initial interval, in seconds (default: 0.5)
152+ max_interval: The longest single delay allowed between retries, in seconds (default: 5)
153+ backoff_coefficient: Coefficient to calculate the next retry interval (default 2.0)
144154
145155 Returns:
146156 The newly created instance object.
@@ -169,20 +179,19 @@ def create(self,
169179 id = self ._http_client .post (INSTANCES_ENDPOINT , json = payload ).text
170180
171181 # Wait for instance to enter provisioning state with timeout
172- MAX_WAIT_TIME = 60 # Maximum wait time in seconds
173- POLL_INTERVAL = 0.5 # Time between status checks
174-
175- start_time = time .time ()
176- while True :
182+ deadline = time .monotonic () + max_wait_time
183+ for i in itertools .count ():
177184 instance = self .get_by_id (id )
178185 if instance .status != InstanceStatus .ORDERED :
179186 return instance
180187
181- if time .time () - start_time > MAX_WAIT_TIME :
188+ now = time .monotonic ()
189+ if now >= deadline :
182190 raise TimeoutError (
183- f"Instance { id } did not enter provisioning state within { MAX_WAIT_TIME } seconds" )
191+ f"Instance { id } did not enter provisioning state within { max_wait_time :.1f } seconds" )
184192
185- time .sleep (POLL_INTERVAL )
193+ interval = min (initial_interval * backoff_coefficient ** i , max_interval , deadline - now )
194+ time .sleep (interval )
186195
187196 def action (self , id_list : Union [List [str ], str ], action : str , volume_ids : Optional [List [str ]] = None ) -> None :
188197 """Performs an action on one or more instances.
0 commit comments