Skip to content

Commit ff6e5e0

Browse files
authored
chore: define explicit state containers for providers (#13423)
1 parent 100783b commit ff6e5e0

File tree

19 files changed

+107
-10
lines changed

19 files changed

+107
-10
lines changed

localstack-core/localstack/services/acm/provider.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
RequestCertificateResponse,
1111
)
1212
from localstack.services import moto
13+
from localstack.state import StateVisitor
1314
from localstack.utils.patch import patch
1415

1516
# reduce the validation wait time from 60 (default) to 10 seconds
@@ -100,6 +101,9 @@ def describe(describe_orig, self):
100101

101102

102103
class AcmProvider(AcmApi):
104+
def accept_state_visitor(self, visitor: StateVisitor):
105+
visitor.visit(acm_models.acm_backends)
106+
103107
@handler("RequestCertificate", expand=False)
104108
def request_certificate(
105109
self,

localstack-core/localstack/services/apigateway/legacy/provider.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,19 @@
118118
from localstack.services.apigateway.legacy.helpers import multi_value_dict_for_list
119119
from localstack.services.apigateway.legacy.invocations import invoke_rest_api_from_request
120120
from localstack.services.apigateway.legacy.router_asf import ApigatewayRouter, to_invocation_context
121-
from localstack.services.apigateway.models import ApiGatewayStore, RestApiContainer
121+
from localstack.services.apigateway.models import (
122+
ApiGatewayStore,
123+
RestApiContainer,
124+
apigateway_stores,
125+
)
122126
from localstack.services.apigateway.next_gen.execute_api.router import (
123127
ApiGatewayRouter as ApiGatewayRouterNextGen,
124128
)
125129
from localstack.services.apigateway.patches import apply_patches
126130
from localstack.services.edge import ROUTER
127131
from localstack.services.moto import call_moto, call_moto_with_request
128132
from localstack.services.plugins import ServiceLifecycleHook
133+
from localstack.state import StateVisitor
129134
from localstack.utils.aws.arns import InvalidArnException, get_partition, parse_arn
130135
from localstack.utils.collections import (
131136
DelSafeDict,
@@ -192,6 +197,12 @@ def on_after_init(self):
192197
apply_patches()
193198
self.router.register_routes()
194199

200+
def accept_state_visitor(self, visitor: StateVisitor):
201+
from moto.apigateway import apigateway_backends
202+
203+
visitor.visit(apigateway_backends)
204+
visitor.visit(apigateway_stores)
205+
195206
@handler("TestInvokeMethod", expand=False)
196207
def test_invoke_method(
197208
self, context: RequestContext, request: TestInvokeMethodRequest

localstack-core/localstack/services/cloudwatch/provider.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from localstack.services.cloudwatch.alarm_scheduler import AlarmScheduler
3636
from localstack.services.edge import ROUTER
3737
from localstack.services.plugins import SERVICE_PLUGINS, ServiceLifecycleHook
38+
from localstack.state import StateVisitor
3839
from localstack.utils.aws import arns
3940
from localstack.utils.aws.arns import extract_account_id_from_arn, lambda_function_name
4041
from localstack.utils.aws.request_context import (
@@ -306,8 +307,13 @@ def __init__(self):
306307
self.tags = TaggingService()
307308
self.alarm_scheduler = None
308309

310+
def accept_state_visitor(self, visitor: StateVisitor):
311+
visitor.visit(cloudwatch_backends)
312+
309313
def on_after_init(self):
310314
ROUTER.add(PATH_GET_RAW_METRICS, self.get_raw_metrics)
315+
316+
def on_before_start(self):
311317
self.start_alarm_scheduler()
312318

313319
def on_before_state_reset(self):
@@ -337,9 +343,10 @@ def start_alarm_scheduler(self):
337343
self.alarm_scheduler = AlarmScheduler()
338344

339345
def shutdown_alarm_scheduler(self):
340-
LOG.debug("stopping cloudwatch scheduler")
341-
self.alarm_scheduler.shutdown_scheduler()
342-
self.alarm_scheduler = None
346+
if self.alarm_scheduler:
347+
LOG.debug("stopping cloudwatch scheduler")
348+
self.alarm_scheduler.shutdown_scheduler()
349+
self.alarm_scheduler = None
343350

344351
def delete_alarms(self, context: RequestContext, alarm_names: AlarmNames, **kwargs) -> None:
345352
moto.call_moto(context)

localstack-core/localstack/services/cloudwatch/provider_v2.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ def accept_state_visitor(self, visitor: StateVisitor):
161161

162162
def on_after_init(self):
163163
ROUTER.add(PATH_GET_RAW_METRICS, self.get_raw_metrics)
164+
165+
def on_before_start(self):
164166
self.start_alarm_scheduler()
165167

166168
def on_before_state_reset(self):
@@ -192,9 +194,10 @@ def start_alarm_scheduler(self):
192194
self.alarm_scheduler = AlarmScheduler()
193195

194196
def shutdown_alarm_scheduler(self):
195-
LOG.debug("stopping cloudwatch scheduler")
196-
self.alarm_scheduler.shutdown_scheduler()
197-
self.alarm_scheduler = None
197+
if self.alarm_scheduler:
198+
LOG.debug("stopping cloudwatch scheduler")
199+
self.alarm_scheduler.shutdown_scheduler()
200+
self.alarm_scheduler = None
198201

199202
def delete_alarms(self, context: RequestContext, alarm_names: AlarmNames, **kwargs) -> None:
200203
"""
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
from localstack.aws.api.config import ConfigApi
2+
from localstack.state import StateVisitor
23

34

45
class ConfigProvider(ConfigApi):
5-
pass
6+
def accept_state_visitor(self, visitor: StateVisitor):
7+
from moto.config.models import config_backends
8+
9+
visitor.visit(config_backends)

localstack-core/localstack/services/dynamodb/provider.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ def __init__(self):
535535
self.server = self._new_dynamodb_server()
536536
self._expired_items_worker = ExpiredItemsWorker()
537537
self._router_rules = []
538+
# TODO: fix _event_forwarder to have lazy instantiation of the ThreadPoolExecutor
538539
self._event_forwarder = EventForwarder()
539540

540541
def on_before_start(self):

localstack-core/localstack/services/dynamodb/v2/provider.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ def on_before_stop(self):
392392

393393
def accept_state_visitor(self, visitor: StateVisitor):
394394
visitor.visit(dynamodb_stores)
395+
# FIXME: DDB v2 does not depend on dynamodbstreams_stores as DynamoDB Local holds all the state
395396
visitor.visit(dynamodbstreams_stores)
396397
visitor.visit(AssetDirectory(self.service, os.path.join(config.dirs.data, self.service)))
397398

localstack-core/localstack/services/dynamodbstreams/provider.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
table_name_from_stream_arn,
3838
)
3939
from localstack.services.plugins import ServiceLifecycleHook
40+
from localstack.state import StateVisitor
4041
from localstack.utils.collections import select_from_typed_dict
4142

4243
LOG = logging.getLogger(__name__)
@@ -57,6 +58,11 @@ class DynamoDBStreamsProvider(DynamodbstreamsApi, ServiceLifecycleHook):
5758
def __init__(self):
5859
self.shard_to_region = {}
5960

61+
def accept_state_visitor(self, visitor: StateVisitor):
62+
from localstack.services.dynamodbstreams.models import dynamodbstreams_stores
63+
64+
visitor.visit(dynamodbstreams_stores)
65+
6066
def describe_stream(
6167
self,
6268
context: RequestContext,

localstack-core/localstack/services/dynamodbstreams/v2/provider.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from localstack.services.dynamodb.v2.provider import DynamoDBProvider, modify_context_region
1919
from localstack.services.dynamodbstreams.dynamodbstreams_api import get_original_region
2020
from localstack.services.plugins import ServiceLifecycleHook
21+
from localstack.state import StateVisitor
2122
from localstack.utils.aws.arns import parse_arn
2223

2324
LOG = logging.getLogger(__name__)
@@ -32,6 +33,11 @@ def __init__(self):
3233
self.server = DynamodbServer.get()
3334
self.shard_to_region = {}
3435

36+
def accept_state_visitor(self, visitor: StateVisitor):
37+
# DynamoDB Streams state is entirely dependent on DynamoDB Local state, and does not hold state itself
38+
# the DynamoDB provider is responsible for the persistence of DDB Streams
39+
pass
40+
3541
def on_after_init(self):
3642
# add response processor specific to ddblocal
3743
handlers.modify_service_response.append(self.service, modify_ddblocal_arns)

localstack-core/localstack/services/ec2/provider.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
from localstack.services.ec2.patches import apply_patches
9595
from localstack.services.moto import call_moto, call_moto_with_request
9696
from localstack.services.plugins import ServiceLifecycleHook
97+
from localstack.state import StateVisitor
9798
from localstack.utils.patch import patch
9899
from localstack.utils.strings import first_char_to_upper, long_uid, short_uid
99100

@@ -107,6 +108,11 @@ class Ec2Provider(Ec2Api, ABC, ServiceLifecycleHook):
107108
def on_after_init(self):
108109
apply_patches()
109110

111+
def accept_state_visitor(self, visitor: StateVisitor):
112+
from moto.ec2.models import ec2_backends
113+
114+
visitor.visit(ec2_backends)
115+
110116
@handler("DescribeAvailabilityZones", expand=False)
111117
def describe_availability_zones(
112118
self,

0 commit comments

Comments
 (0)