|
8 | 8 | from typing import Callable, Dict, List, Optional, Protocol, Tuple
|
9 | 9 |
|
10 | 10 | from plugin import Plugin, PluginLifecycleListener, PluginManager, PluginSpec
|
11 |
| -from readerwriterlock import rwlock |
12 |
| -from werkzeug import Request |
13 | 11 |
|
14 | 12 | from localstack import config
|
15 | 13 | from localstack.aws.skeleton import DispatchTable
|
|
29 | 27 | _default = object() # sentinel object indicating a default value
|
30 | 28 |
|
31 | 29 |
|
32 |
| -# --------------------------- |
33 |
| -# STATE SERIALIZER INTERFACE |
34 |
| -# --------------------------- |
35 |
| - |
36 |
| - |
37 |
| -class PersistenceContext: |
38 |
| - state_dir: str |
39 |
| - lock: rwlock.RWLockable |
40 |
| - |
41 |
| - def __init__(self, state_dir: str = None, lock: rwlock.RWLockable = None): |
42 |
| - # state dir (within DATA_DIR) of currently processed API in local file system |
43 |
| - self.state_dir = state_dir |
44 |
| - # read-write lock for concurrency control of incoming requests |
45 |
| - self.lock = lock |
46 |
| - |
47 |
| - |
48 |
| -class StateSerializer(abc.ABC): |
49 |
| - """A state serializer encapsulates the logic of persisting and loading service state to/from disk.""" |
50 |
| - |
51 |
| - @abc.abstractmethod |
52 |
| - def restore_state(self, context: PersistenceContext): |
53 |
| - """Restore state from the underlying persistence file""" |
54 |
| - pass |
55 |
| - |
56 |
| - @abc.abstractmethod |
57 |
| - def update_state(self, context: PersistenceContext, request: Request): |
58 |
| - """Update persistence state based on the incoming request""" |
59 |
| - pass |
60 |
| - |
61 |
| - @abc.abstractmethod |
62 |
| - def is_write_request(self, request: Request) -> bool: |
63 |
| - """Returns whether the given request is a write request that should trigger serialization""" |
64 |
| - return False |
65 |
| - |
66 |
| - def get_lock_for_request(self, request: Request) -> Optional[rwlock.Lockable]: |
67 |
| - """Returns a lock (or None) that should be used to guard the given request, for concurrency control""" |
68 |
| - return None |
69 |
| - |
70 |
| - def get_context(self) -> PersistenceContext: |
71 |
| - """Returns the current persistence context""" |
72 |
| - return None |
73 |
| - |
74 |
| - |
75 |
| -class StateSerializerComposite(StateSerializer): |
76 |
| - """Composite state serializer that delegates the requests to a list of underlying concrete serializers""" |
77 |
| - |
78 |
| - def __init__(self, serializers: List[StateSerializer] = None): |
79 |
| - self.serializers: List[StateSerializer] = serializers or [] |
80 |
| - |
81 |
| - def restore_state(self, context: PersistenceContext): |
82 |
| - for serializer in self.serializers: |
83 |
| - serializer.restore_state(context) |
84 |
| - |
85 |
| - def update_state(self, context: PersistenceContext, request: Request): |
86 |
| - for serializer in self.serializers: |
87 |
| - serializer.update_state(context, request) |
88 |
| - |
89 |
| - def is_write_request(self, request: Request) -> bool: |
90 |
| - return any(ser.is_write_request(request) for ser in self.serializers) |
91 |
| - |
92 |
| - def get_lock_for_request(self, request: Request) -> Optional[rwlock.Lockable]: |
93 |
| - if self.serializers: |
94 |
| - return self.serializers[0].get_lock_for_request( |
95 |
| - request |
96 |
| - ) # return lock from first serializer |
97 |
| - |
98 |
| - def get_context(self) -> PersistenceContext: |
99 |
| - if self.serializers: |
100 |
| - return self.serializers[0].get_context() # return context from first serializer |
101 |
| - |
102 |
| - |
103 |
| -# maps service names to serializers (TODO: to be encapsulated in ServicePlugin instances) |
104 |
| -SERIALIZERS: Dict[str, StateSerializer] = {} |
105 |
| - |
106 |
| - |
107 | 30 | # -----------------
|
108 | 31 | # PLUGIN UTILITIES
|
109 | 32 | # -----------------
|
|
0 commit comments