| 329 | |
| 330 | @with_current_context(partial(register_feature_id, 'WAITER')) |
| 331 | def wait(self, **kwargs): |
| 332 | acceptors = list(self.config.acceptors) |
| 333 | current_state = 'waiting' |
| 334 | # pop the invocation specific config |
| 335 | config = kwargs.pop('WaiterConfig', {}) |
| 336 | sleep_amount = config.get('Delay', self.config.delay) |
| 337 | max_attempts = config.get('MaxAttempts', self.config.max_attempts) |
| 338 | last_matched_acceptor = None |
| 339 | num_attempts = 0 |
| 340 | |
| 341 | while True: |
| 342 | response = self._operation_method(**kwargs) |
| 343 | num_attempts += 1 |
| 344 | for acceptor in acceptors: |
| 345 | if acceptor.matcher_func(response): |
| 346 | last_matched_acceptor = acceptor |
| 347 | current_state = acceptor.state |
| 348 | break |
| 349 | else: |
| 350 | # If none of the acceptors matched, we should |
| 351 | # transition to the failure state if an error |
| 352 | # response was received. |
| 353 | if is_valid_waiter_error(response): |
| 354 | # Transition to a failure state, which we |
| 355 | # can just handle here by raising an exception. |
| 356 | raise WaiterError( |
| 357 | name=self.name, |
| 358 | reason='An error occurred ({}): {}'.format( |
| 359 | response['Error'].get('Code', 'Unknown'), |
| 360 | response['Error'].get('Message', 'Unknown'), |
| 361 | ), |
| 362 | last_response=response, |
| 363 | ) |
| 364 | if current_state == 'success': |
| 365 | logger.debug( |
| 366 | "Waiting complete, waiter matched the " "success state." |
| 367 | ) |
| 368 | return |
| 369 | if current_state == 'failure': |
| 370 | reason = f'Waiter encountered a terminal failure state: {acceptor.explanation}' |
| 371 | raise WaiterError( |
| 372 | name=self.name, |
| 373 | reason=reason, |
| 374 | last_response=response, |
| 375 | ) |
| 376 | if num_attempts >= max_attempts: |
| 377 | if last_matched_acceptor is None: |
| 378 | reason = 'Max attempts exceeded' |
| 379 | else: |
| 380 | reason = f'Max attempts exceeded. Previously accepted state: {acceptor.explanation}' |
| 381 | raise WaiterError( |
| 382 | name=self.name, |
| 383 | reason=reason, |
| 384 | last_response=response, |
| 385 | ) |
| 386 | time.sleep(sleep_amount) |