|
12 | 12 | import urllib.parse |
13 | 13 | import sys |
14 | 14 |
|
| 15 | +# thread safe, memoized, provider builder. |
| 16 | +from threading import Lock |
| 17 | + |
15 | 18 | import botocore.exceptions |
16 | 19 | from botocore.config import Config |
17 | 20 |
|
@@ -448,17 +451,37 @@ def generate_stack_policy_args(stack_policy=None): |
448 | 451 |
|
449 | 452 |
|
450 | 453 | class ProviderBuilder(object): |
451 | | - """Implements a ProviderBuilder for the AWS provider.""" |
| 454 | + """Implements a Memoized ProviderBuilder for the AWS provider.""" |
452 | 455 |
|
453 | 456 | def __init__(self, region=None, **kwargs): |
454 | 457 | self.region = region |
455 | 458 | self.kwargs = kwargs |
| 459 | + self.providers = {} |
| 460 | + self.lock = Lock() |
456 | 461 |
|
457 | 462 | def build(self, region=None, profile=None): |
458 | | - if not region: |
459 | | - region = self.region |
460 | | - session = get_session(region=region, profile=profile) |
461 | | - return Provider(session, region=region, **self.kwargs) |
| 463 | + """Get or create the provider for the given region and profile.""" |
| 464 | + |
| 465 | + with self.lock: |
| 466 | + # memoization lookup key derived from region + profile. |
| 467 | + key = "{}-{}".format(profile, region) |
| 468 | + try: |
| 469 | + # assume provider is in provider dictionary. |
| 470 | + provider = self.providers[key] |
| 471 | + except KeyError: |
| 472 | + msg = "Missed memoized lookup ({}), creating new AWS Provider." |
| 473 | + logger.debug(msg.format(key)) |
| 474 | + if not region: |
| 475 | + region = self.region |
| 476 | + # memoize the result for later. |
| 477 | + self.providers[key] = Provider( |
| 478 | + get_session(region=region, profile=profile), |
| 479 | + region=region, |
| 480 | + **self.kwargs |
| 481 | + ) |
| 482 | + provider = self.providers[key] |
| 483 | + |
| 484 | + return provider |
462 | 485 |
|
463 | 486 |
|
464 | 487 | class Provider(BaseProvider): |
|
0 commit comments