kurrentdbclient 0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kurrentdbclient/__init__.py +49 -0
- kurrentdbclient/asyncio_client.py +1662 -0
- kurrentdbclient/client.py +1914 -0
- kurrentdbclient/common.py +535 -0
- kurrentdbclient/connection.py +107 -0
- kurrentdbclient/connection_spec.py +371 -0
- kurrentdbclient/events.py +141 -0
- kurrentdbclient/exceptions.py +239 -0
- kurrentdbclient/gossip.py +104 -0
- kurrentdbclient/instrumentation/__init__.py +0 -0
- kurrentdbclient/instrumentation/opentelemetry/__init__.py +185 -0
- kurrentdbclient/instrumentation/opentelemetry/attributes.py +20 -0
- kurrentdbclient/instrumentation/opentelemetry/grpc.py +165 -0
- kurrentdbclient/instrumentation/opentelemetry/package.py +2 -0
- kurrentdbclient/instrumentation/opentelemetry/spanners.py +1097 -0
- kurrentdbclient/instrumentation/opentelemetry/utils.py +199 -0
- kurrentdbclient/instrumentation/opentelemetry/version.py +2 -0
- kurrentdbclient/persistent.py +1982 -0
- kurrentdbclient/projections.py +735 -0
- kurrentdbclient/protos/Grpc/cluster_pb2.py +92 -0
- kurrentdbclient/protos/Grpc/cluster_pb2.pyi +765 -0
- kurrentdbclient/protos/Grpc/cluster_pb2_grpc.py +514 -0
- kurrentdbclient/protos/Grpc/code_pb2.py +37 -0
- kurrentdbclient/protos/Grpc/code_pb2.pyi +357 -0
- kurrentdbclient/protos/Grpc/code_pb2_grpc.py +24 -0
- kurrentdbclient/protos/Grpc/gossip_pb2.py +46 -0
- kurrentdbclient/protos/Grpc/gossip_pb2.pyi +126 -0
- kurrentdbclient/protos/Grpc/gossip_pb2_grpc.py +98 -0
- kurrentdbclient/protos/Grpc/persistent_pb2.py +140 -0
- kurrentdbclient/protos/Grpc/persistent_pb2.pyi +1135 -0
- kurrentdbclient/protos/Grpc/persistent_pb2_grpc.py +399 -0
- kurrentdbclient/protos/Grpc/projections_pb2.py +99 -0
- kurrentdbclient/protos/Grpc/projections_pb2.pyi +558 -0
- kurrentdbclient/protos/Grpc/projections_pb2_grpc.py +485 -0
- kurrentdbclient/protos/Grpc/shared_pb2.py +62 -0
- kurrentdbclient/protos/Grpc/shared_pb2.pyi +218 -0
- kurrentdbclient/protos/Grpc/shared_pb2_grpc.py +24 -0
- kurrentdbclient/protos/Grpc/status_pb2.py +39 -0
- kurrentdbclient/protos/Grpc/status_pb2.pyi +67 -0
- kurrentdbclient/protos/Grpc/status_pb2_grpc.py +24 -0
- kurrentdbclient/protos/Grpc/streams_pb2.py +132 -0
- kurrentdbclient/protos/Grpc/streams_pb2.pyi +1038 -0
- kurrentdbclient/protos/Grpc/streams_pb2_grpc.py +269 -0
- kurrentdbclient/py.typed +0 -0
- kurrentdbclient/streams.py +1400 -0
- kurrentdbclient-0.3.dist-info/LICENSE +29 -0
- kurrentdbclient-0.3.dist-info/METADATA +3769 -0
- kurrentdbclient-0.3.dist-info/RECORD +49 -0
- kurrentdbclient-0.3.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1914 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import random
|
|
6
|
+
import sys
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from functools import wraps
|
|
9
|
+
from threading import Event, Lock
|
|
10
|
+
from time import sleep
|
|
11
|
+
from typing import (
|
|
12
|
+
Any,
|
|
13
|
+
Callable,
|
|
14
|
+
Dict,
|
|
15
|
+
Iterable,
|
|
16
|
+
Optional,
|
|
17
|
+
Sequence,
|
|
18
|
+
Tuple,
|
|
19
|
+
TypeVar,
|
|
20
|
+
Union,
|
|
21
|
+
cast,
|
|
22
|
+
overload,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
import grpc
|
|
26
|
+
from typing_extensions import Literal
|
|
27
|
+
|
|
28
|
+
from kurrentdbclient.common import (
|
|
29
|
+
DEFAULT_CHECKPOINT_INTERVAL_MULTIPLIER,
|
|
30
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
31
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_EVENT_BUFFER_SIZE,
|
|
32
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
33
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
34
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_BATCH_SIZE,
|
|
35
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_DELAY,
|
|
36
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
37
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
38
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
39
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
40
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
41
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
42
|
+
DEFAULT_PERSISTENT_SUBSCRIPTION_STOPPING_GRACE,
|
|
43
|
+
DEFAULT_WINDOW_SIZE,
|
|
44
|
+
AbstractCatchupSubscription,
|
|
45
|
+
AbstractPersistentSubscription,
|
|
46
|
+
AbstractReadResponse,
|
|
47
|
+
BasicAuthCallCredentials,
|
|
48
|
+
GrpcOptions,
|
|
49
|
+
)
|
|
50
|
+
from kurrentdbclient.connection import KurrentDBConnection
|
|
51
|
+
from kurrentdbclient.connection_spec import (
|
|
52
|
+
NODE_PREFERENCE_FOLLOWER,
|
|
53
|
+
NODE_PREFERENCE_LEADER,
|
|
54
|
+
NODE_PREFERENCE_RANDOM,
|
|
55
|
+
NODE_PREFERENCE_REPLICA,
|
|
56
|
+
URI_SCHEMES_NON_DISCOVER,
|
|
57
|
+
ConnectionSpec,
|
|
58
|
+
)
|
|
59
|
+
from kurrentdbclient.events import NewEvent, RecordedEvent
|
|
60
|
+
from kurrentdbclient.exceptions import (
|
|
61
|
+
DiscoveryFailed,
|
|
62
|
+
FollowerNotFound,
|
|
63
|
+
GrpcError,
|
|
64
|
+
LeaderNotFound,
|
|
65
|
+
NodeIsNotLeader,
|
|
66
|
+
NotFound,
|
|
67
|
+
ReadOnlyReplicaNotFound,
|
|
68
|
+
ServiceUnavailable,
|
|
69
|
+
)
|
|
70
|
+
from kurrentdbclient.gossip import (
|
|
71
|
+
NODE_STATE_FOLLOWER,
|
|
72
|
+
NODE_STATE_LEADER,
|
|
73
|
+
NODE_STATE_REPLICA,
|
|
74
|
+
ClusterMember,
|
|
75
|
+
GossipService,
|
|
76
|
+
)
|
|
77
|
+
from kurrentdbclient.persistent import (
|
|
78
|
+
ConsumerStrategy,
|
|
79
|
+
PersistentSubscriptionsService,
|
|
80
|
+
SubscriptionInfo,
|
|
81
|
+
)
|
|
82
|
+
from kurrentdbclient.projections import (
|
|
83
|
+
ProjectionsService,
|
|
84
|
+
ProjectionState,
|
|
85
|
+
ProjectionStatistics,
|
|
86
|
+
)
|
|
87
|
+
from kurrentdbclient.streams import StreamsService, StreamState
|
|
88
|
+
|
|
89
|
+
# Matches the 'type' of "system" events.
|
|
90
|
+
KDB_SYSTEM_EVENTS_REGEX = r"\$.+"
|
|
91
|
+
# Matches the 'type' of "PersistentConfig" events.
|
|
92
|
+
KDB_PERSISTENT_CONFIG_EVENTS_REGEX = r"PersistentConfig\d+"
|
|
93
|
+
|
|
94
|
+
DEFAULT_EXCLUDE_FILTER = (
|
|
95
|
+
KDB_SYSTEM_EVENTS_REGEX,
|
|
96
|
+
KDB_PERSISTENT_CONFIG_EVENTS_REGEX,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
_TCallable = TypeVar("_TCallable", bound=Callable[..., Any])
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def autoreconnect(f: _TCallable) -> _TCallable:
|
|
103
|
+
@wraps(f)
|
|
104
|
+
def autoreconnect_decorator(*args: Any, **kwargs: Any) -> Any:
|
|
105
|
+
client = args[0]
|
|
106
|
+
assert isinstance(client, KurrentDBClient)
|
|
107
|
+
try:
|
|
108
|
+
return f(*args, **kwargs)
|
|
109
|
+
|
|
110
|
+
except NodeIsNotLeader as e:
|
|
111
|
+
if (
|
|
112
|
+
client.connection_spec.options.NodePreference == NODE_PREFERENCE_LEADER
|
|
113
|
+
and not (
|
|
114
|
+
client.connection_spec.scheme in URI_SCHEMES_NON_DISCOVER
|
|
115
|
+
and len(client.connection_spec.targets) == 1
|
|
116
|
+
)
|
|
117
|
+
):
|
|
118
|
+
client.reconnect(e.leader_grpc_target)
|
|
119
|
+
sleep(0.1)
|
|
120
|
+
return f(*args, **kwargs)
|
|
121
|
+
else:
|
|
122
|
+
raise
|
|
123
|
+
|
|
124
|
+
except ValueError as e:
|
|
125
|
+
s = str(e)
|
|
126
|
+
if "Channel closed!" in s or "Cannot invoke RPC on closed channel!" in s:
|
|
127
|
+
client.reconnect()
|
|
128
|
+
sleep(0.1)
|
|
129
|
+
return f(*args, **kwargs)
|
|
130
|
+
else: # pragma: no cover
|
|
131
|
+
raise
|
|
132
|
+
|
|
133
|
+
except ServiceUnavailable:
|
|
134
|
+
client.reconnect()
|
|
135
|
+
sleep(0.1)
|
|
136
|
+
return f(*args, **kwargs)
|
|
137
|
+
|
|
138
|
+
return cast(_TCallable, autoreconnect_decorator)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def retrygrpc(f: _TCallable) -> _TCallable:
|
|
142
|
+
@wraps(f)
|
|
143
|
+
def retrygrpc_decorator(*args: Any, **kwargs: Any) -> Any:
|
|
144
|
+
try:
|
|
145
|
+
return f(*args, **kwargs)
|
|
146
|
+
except GrpcError:
|
|
147
|
+
sleep(0.1)
|
|
148
|
+
return f(*args, **kwargs)
|
|
149
|
+
|
|
150
|
+
return cast(_TCallable, retrygrpc_decorator)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class BaseKurrentDBClient(ABC):
|
|
154
|
+
def __init__(
|
|
155
|
+
self,
|
|
156
|
+
uri: Optional[str] = None,
|
|
157
|
+
*,
|
|
158
|
+
root_certificates: Optional[Union[str, bytes]] = None,
|
|
159
|
+
private_key: Optional[Union[str, bytes]] = None,
|
|
160
|
+
certificate_chain: Optional[Union[str, bytes]] = None,
|
|
161
|
+
) -> None:
|
|
162
|
+
self._is_closed = False
|
|
163
|
+
self.root_certificates = (
|
|
164
|
+
root_certificates.encode()
|
|
165
|
+
if isinstance(root_certificates, str)
|
|
166
|
+
else root_certificates
|
|
167
|
+
)
|
|
168
|
+
self.private_key = (
|
|
169
|
+
private_key.encode() if isinstance(private_key, str) else private_key
|
|
170
|
+
)
|
|
171
|
+
self.certificate_chain = (
|
|
172
|
+
certificate_chain.encode()
|
|
173
|
+
if isinstance(certificate_chain, str)
|
|
174
|
+
else certificate_chain
|
|
175
|
+
)
|
|
176
|
+
self.connection_spec = ConnectionSpec(uri)
|
|
177
|
+
|
|
178
|
+
# Load private_key from UserKeyFile if specified
|
|
179
|
+
if self.connection_spec.options.UserKeyFile:
|
|
180
|
+
with open(self.connection_spec.options.UserKeyFile, "r+b") as f:
|
|
181
|
+
self.private_key = f.read()
|
|
182
|
+
else:
|
|
183
|
+
self.private_key = None
|
|
184
|
+
|
|
185
|
+
# Load certificate_chain from UserCertFile if specified
|
|
186
|
+
if self.connection_spec.options.UserCertFile:
|
|
187
|
+
with open(self.connection_spec.options.UserCertFile, "r+b") as f:
|
|
188
|
+
self.certificate_chain = f.read()
|
|
189
|
+
else:
|
|
190
|
+
self.certificate_chain = None
|
|
191
|
+
|
|
192
|
+
# Load root_certificates from TlsCaFile if specified
|
|
193
|
+
if self.connection_spec.options.TlsCaFile:
|
|
194
|
+
with open(self.connection_spec.options.TlsCaFile, "r+b") as f:
|
|
195
|
+
self.root_certificates = f.read()
|
|
196
|
+
|
|
197
|
+
self._default_deadline = self.connection_spec.options.DefaultDeadline
|
|
198
|
+
|
|
199
|
+
self.grpc_options: GrpcOptions = (
|
|
200
|
+
("grpc.max_receive_message_length", 17 * 1024 * 1024),
|
|
201
|
+
)
|
|
202
|
+
if self.connection_spec.options.KeepAliveInterval is not None:
|
|
203
|
+
self.grpc_options += (
|
|
204
|
+
("grpc.keepalive_ms", self.connection_spec.options.KeepAliveInterval),
|
|
205
|
+
)
|
|
206
|
+
if self.connection_spec.options.KeepAliveTimeout is not None:
|
|
207
|
+
self.grpc_options += (
|
|
208
|
+
(
|
|
209
|
+
"grpc.keepalive_timeout_ms",
|
|
210
|
+
self.connection_spec.options.KeepAliveTimeout,
|
|
211
|
+
),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
self._call_metadata = (
|
|
215
|
+
("connection-name", self.connection_spec.options.ConnectionName),
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
self._call_credentials = self.construct_call_credentials(
|
|
219
|
+
self.connection_spec.username, self.connection_spec.password
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
@abstractmethod
|
|
224
|
+
def connection_target(self) -> str:
|
|
225
|
+
pass # pragma: no cover
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def is_closed(self) -> bool:
|
|
229
|
+
return self._is_closed
|
|
230
|
+
|
|
231
|
+
def construct_call_credentials(
|
|
232
|
+
self, username: Optional[str], password: Optional[str]
|
|
233
|
+
) -> Optional[grpc.CallCredentials]:
|
|
234
|
+
if username and password and self.connection_spec.options.Tls is True:
|
|
235
|
+
return grpc.metadata_call_credentials(
|
|
236
|
+
BasicAuthCallCredentials(username, password)
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
return None
|
|
240
|
+
|
|
241
|
+
def _select_preferred_member(
|
|
242
|
+
self, cluster_members: Sequence[ClusterMember]
|
|
243
|
+
) -> ClusterMember:
|
|
244
|
+
node_preference = self.connection_spec.options.NodePreference
|
|
245
|
+
if node_preference == NODE_PREFERENCE_LEADER:
|
|
246
|
+
leaders = [c for c in cluster_members if c.state == NODE_STATE_LEADER]
|
|
247
|
+
if len(leaders) != 1: # pragma: no cover
|
|
248
|
+
# Todo: Cover this with a test.
|
|
249
|
+
raise LeaderNotFound(f"Expected one leader, discovered {len(leaders)}")
|
|
250
|
+
preferred_member = leaders[0]
|
|
251
|
+
elif node_preference == NODE_PREFERENCE_FOLLOWER:
|
|
252
|
+
followers = [c for c in cluster_members if c.state == NODE_STATE_FOLLOWER]
|
|
253
|
+
if len(followers) == 0:
|
|
254
|
+
raise FollowerNotFound()
|
|
255
|
+
preferred_member = random.choice(followers)
|
|
256
|
+
elif node_preference == NODE_PREFERENCE_REPLICA:
|
|
257
|
+
replicas = [c for c in cluster_members if c.state == NODE_STATE_REPLICA]
|
|
258
|
+
if len(replicas) == 0:
|
|
259
|
+
raise ReadOnlyReplicaNotFound()
|
|
260
|
+
# Todo: Cover this with a test.
|
|
261
|
+
preferred_member = random.choice(replicas) # pragma: no cover
|
|
262
|
+
else:
|
|
263
|
+
assert node_preference == NODE_PREFERENCE_RANDOM
|
|
264
|
+
assert len(cluster_members) > 0
|
|
265
|
+
preferred_member = random.choice(cluster_members)
|
|
266
|
+
return preferred_member
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class KurrentDBClient(BaseKurrentDBClient):
|
|
270
|
+
"""
|
|
271
|
+
Encapsulates the KurrentDB gRPC API.
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
def __init__(
|
|
275
|
+
self,
|
|
276
|
+
uri: Optional[str] = None,
|
|
277
|
+
*,
|
|
278
|
+
root_certificates: Optional[Union[str, bytes]] = None,
|
|
279
|
+
private_key: Optional[Union[str, bytes]] = None,
|
|
280
|
+
certificate_chain: Optional[Union[str, bytes]] = None,
|
|
281
|
+
) -> None:
|
|
282
|
+
super().__init__(
|
|
283
|
+
uri,
|
|
284
|
+
root_certificates=root_certificates,
|
|
285
|
+
private_key=private_key,
|
|
286
|
+
certificate_chain=certificate_chain,
|
|
287
|
+
)
|
|
288
|
+
self._is_reconnection_required = Event()
|
|
289
|
+
self._reconnection_lock = Lock()
|
|
290
|
+
self._connection = self._connect()
|
|
291
|
+
|
|
292
|
+
# self._batch_append_futures_lock = Lock()
|
|
293
|
+
# self._batch_append_futures_queue = BatchAppendFutureQueue()
|
|
294
|
+
# self._batch_append_thread = Thread(
|
|
295
|
+
# target=self._batch_append_future_result_loop, daemon=True
|
|
296
|
+
# )
|
|
297
|
+
# self._batch_append_thread.start()
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def connection_target(self) -> str:
|
|
301
|
+
return self._connection.grpc_target
|
|
302
|
+
|
|
303
|
+
@property
|
|
304
|
+
def streams(self) -> StreamsService:
|
|
305
|
+
return self._connection.streams
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
def persistent_subscriptions(self) -> PersistentSubscriptionsService:
|
|
309
|
+
return self._connection.persistent_subscriptions
|
|
310
|
+
|
|
311
|
+
@property
|
|
312
|
+
def gossip(self) -> GossipService:
|
|
313
|
+
return self._connection.gossip
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def projections(self) -> ProjectionsService:
|
|
317
|
+
return self._connection.projections
|
|
318
|
+
|
|
319
|
+
def _connect(self, grpc_target: Optional[str] = None) -> KurrentDBConnection:
|
|
320
|
+
if grpc_target:
|
|
321
|
+
# Just connect to the given target.
|
|
322
|
+
return self._construct_esdb_connection(grpc_target)
|
|
323
|
+
if (
|
|
324
|
+
self.connection_spec.scheme in URI_SCHEMES_NON_DISCOVER
|
|
325
|
+
and len(self.connection_spec.targets) == 1
|
|
326
|
+
):
|
|
327
|
+
# Just connect to the specified target.
|
|
328
|
+
return self._construct_esdb_connection(
|
|
329
|
+
grpc_target=self.connection_spec.targets[0],
|
|
330
|
+
)
|
|
331
|
+
# Discover preferred node in cluster.
|
|
332
|
+
return self._discover_preferred_node()
|
|
333
|
+
|
|
334
|
+
def _discover_preferred_node(self) -> KurrentDBConnection:
|
|
335
|
+
attempts = self.connection_spec.options.MaxDiscoverAttempts
|
|
336
|
+
assert attempts > 0
|
|
337
|
+
if self.connection_spec.scheme in URI_SCHEMES_NON_DISCOVER:
|
|
338
|
+
grpc_options: GrpcOptions = ()
|
|
339
|
+
else:
|
|
340
|
+
grpc_options = (("grpc.lb_policy_name", "round_robin"),)
|
|
341
|
+
while True:
|
|
342
|
+
# Attempt to discover preferred node.
|
|
343
|
+
try:
|
|
344
|
+
last_exception: Optional[Exception] = None
|
|
345
|
+
for grpc_target in self.connection_spec.targets:
|
|
346
|
+
connection = self._construct_esdb_connection(
|
|
347
|
+
grpc_target=grpc_target,
|
|
348
|
+
grpc_options=grpc_options,
|
|
349
|
+
)
|
|
350
|
+
try:
|
|
351
|
+
cluster_members = connection.gossip.read(
|
|
352
|
+
timeout=self.connection_spec.options.GossipTimeout,
|
|
353
|
+
metadata=self._call_metadata,
|
|
354
|
+
credentials=self._call_credentials,
|
|
355
|
+
)
|
|
356
|
+
except GrpcError as e:
|
|
357
|
+
last_exception = e
|
|
358
|
+
connection.close()
|
|
359
|
+
else:
|
|
360
|
+
break
|
|
361
|
+
else:
|
|
362
|
+
msg = (
|
|
363
|
+
"Failed to obtain cluster info from"
|
|
364
|
+
f" '{','.join(self.connection_spec.targets)}':"
|
|
365
|
+
f" {str(last_exception)}"
|
|
366
|
+
)
|
|
367
|
+
raise DiscoveryFailed(msg) from last_exception
|
|
368
|
+
|
|
369
|
+
preferred_member = self._select_preferred_member(cluster_members)
|
|
370
|
+
|
|
371
|
+
except DiscoveryFailed:
|
|
372
|
+
attempts -= 1
|
|
373
|
+
if attempts == 0:
|
|
374
|
+
raise
|
|
375
|
+
else:
|
|
376
|
+
sleep(self.connection_spec.options.DiscoveryInterval / 1000)
|
|
377
|
+
else:
|
|
378
|
+
break
|
|
379
|
+
|
|
380
|
+
# Maybe close connection and connect to preferred node.
|
|
381
|
+
if len(cluster_members) > 1: # forgive not "advertising" single node
|
|
382
|
+
preferred_target = f"{preferred_member.address}:{preferred_member.port}"
|
|
383
|
+
if preferred_target != connection.grpc_target:
|
|
384
|
+
connection.close()
|
|
385
|
+
connection = self._construct_esdb_connection(preferred_target)
|
|
386
|
+
|
|
387
|
+
return connection
|
|
388
|
+
|
|
389
|
+
def reconnect(self, grpc_target: Optional[str] = None) -> None:
|
|
390
|
+
self._is_reconnection_required.set()
|
|
391
|
+
with self._reconnection_lock:
|
|
392
|
+
if self._is_reconnection_required.is_set():
|
|
393
|
+
new_conn = self._connect(grpc_target)
|
|
394
|
+
old_conn, self._connection = self._connection, new_conn
|
|
395
|
+
old_conn.close()
|
|
396
|
+
self._is_reconnection_required.clear()
|
|
397
|
+
else: # pragma: no cover
|
|
398
|
+
# Todo: Test with concurrent writes to wrong node state.
|
|
399
|
+
pass
|
|
400
|
+
|
|
401
|
+
def _construct_esdb_connection(
|
|
402
|
+
self, grpc_target: str, grpc_options: GrpcOptions = ()
|
|
403
|
+
) -> KurrentDBConnection:
|
|
404
|
+
return KurrentDBConnection(
|
|
405
|
+
grpc_channel=self._construct_grpc_channel(grpc_target, grpc_options),
|
|
406
|
+
grpc_target=grpc_target,
|
|
407
|
+
connection_spec=self.connection_spec,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
def _construct_grpc_channel(
|
|
411
|
+
self, grpc_target: str, grpc_options: GrpcOptions = ()
|
|
412
|
+
) -> grpc.Channel:
|
|
413
|
+
grpc_options = self.grpc_options + grpc_options
|
|
414
|
+
if self.connection_spec.options.Tls is True:
|
|
415
|
+
channel_credentials = grpc.ssl_channel_credentials(
|
|
416
|
+
root_certificates=self.root_certificates,
|
|
417
|
+
private_key=self.private_key,
|
|
418
|
+
certificate_chain=self.certificate_chain,
|
|
419
|
+
)
|
|
420
|
+
grpc_channel = grpc.secure_channel(
|
|
421
|
+
target=grpc_target,
|
|
422
|
+
credentials=channel_credentials,
|
|
423
|
+
options=grpc_options,
|
|
424
|
+
)
|
|
425
|
+
else:
|
|
426
|
+
grpc_channel = grpc.insecure_channel(
|
|
427
|
+
target=grpc_target, options=grpc_options
|
|
428
|
+
)
|
|
429
|
+
return grpc_channel
|
|
430
|
+
|
|
431
|
+
# def _batch_append_future_result_loop(self) -> None:
|
|
432
|
+
# # while self._channel_connectivity_state is not ChannelConnectivity.SHUTDOWN:
|
|
433
|
+
# credentials = None
|
|
434
|
+
# try:
|
|
435
|
+
# self.streams.batch_append_multiplexed(
|
|
436
|
+
# futures_queue=self._batch_append_futures_queue,
|
|
437
|
+
# timeout=None,
|
|
438
|
+
# metadata=self._call_metadata,
|
|
439
|
+
# credentials=credentials or self._call_credentials,
|
|
440
|
+
# )
|
|
441
|
+
# except KurrentDBClientException as e:
|
|
442
|
+
# self._clear_batch_append_futures_queue(e)
|
|
443
|
+
# else:
|
|
444
|
+
# self._clear_batch_append_futures_queue( # pragma: no cover
|
|
445
|
+
# KurrentDBClientException("Request not sent")
|
|
446
|
+
# )
|
|
447
|
+
#
|
|
448
|
+
# def _clear_batch_append_futures_queue(
|
|
449
|
+
# self, error: KurrentDBClientException
|
|
450
|
+
# ) -> None:
|
|
451
|
+
# with self._batch_append_futures_lock:
|
|
452
|
+
# try:
|
|
453
|
+
# while True:
|
|
454
|
+
# future = self._batch_append_futures_queue.get(block=False)
|
|
455
|
+
# future.set_exception(error) # pragma: no cover
|
|
456
|
+
# except Empty:
|
|
457
|
+
# pass
|
|
458
|
+
#
|
|
459
|
+
# def append_events_multiplexed(
|
|
460
|
+
# self,
|
|
461
|
+
# stream_name: str,
|
|
462
|
+
# *,
|
|
463
|
+
# current_version: Union[int, StreamState],
|
|
464
|
+
# events: Iterable[NewEvent],
|
|
465
|
+
# timeout: Optional[float] = None,
|
|
466
|
+
# ) -> int:
|
|
467
|
+
# timeout = timeout if timeout is not None else self._default_deadline
|
|
468
|
+
# batch_append_request = BatchAppendRequest(
|
|
469
|
+
# stream_name=stream_name, current_version=current_version, events=events
|
|
470
|
+
# )
|
|
471
|
+
# future = BatchAppendFuture(batch_append_request=batch_append_request)
|
|
472
|
+
# with self._batch_append_futures_lock:
|
|
473
|
+
# self._batch_append_futures_queue.put(future)
|
|
474
|
+
# response = future.result(timeout=timeout)
|
|
475
|
+
# assert isinstance(response.commit_position, int)
|
|
476
|
+
# return response.commit_position
|
|
477
|
+
|
|
478
|
+
@retrygrpc
|
|
479
|
+
@autoreconnect
|
|
480
|
+
def append_events(
|
|
481
|
+
self,
|
|
482
|
+
stream_name: str,
|
|
483
|
+
*,
|
|
484
|
+
current_version: Union[int, StreamState],
|
|
485
|
+
events: Iterable[NewEvent],
|
|
486
|
+
timeout: Optional[float] = None,
|
|
487
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
488
|
+
) -> int:
|
|
489
|
+
return self.append_to_stream(
|
|
490
|
+
stream_name=stream_name,
|
|
491
|
+
current_version=current_version,
|
|
492
|
+
events=events,
|
|
493
|
+
timeout=timeout,
|
|
494
|
+
credentials=credentials,
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
def append_event(
|
|
498
|
+
self,
|
|
499
|
+
stream_name: str,
|
|
500
|
+
*,
|
|
501
|
+
current_version: Union[int, StreamState],
|
|
502
|
+
event: NewEvent,
|
|
503
|
+
timeout: Optional[float] = None,
|
|
504
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
505
|
+
) -> int:
|
|
506
|
+
"""
|
|
507
|
+
Appends a new event to the named stream.
|
|
508
|
+
"""
|
|
509
|
+
return self.append_to_stream(
|
|
510
|
+
stream_name=stream_name,
|
|
511
|
+
current_version=current_version,
|
|
512
|
+
events=event,
|
|
513
|
+
timeout=timeout,
|
|
514
|
+
credentials=credentials,
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
@retrygrpc
|
|
518
|
+
@autoreconnect
|
|
519
|
+
def append_to_stream(
|
|
520
|
+
self,
|
|
521
|
+
/,
|
|
522
|
+
stream_name: str,
|
|
523
|
+
*,
|
|
524
|
+
current_version: Union[int, StreamState],
|
|
525
|
+
events: Union[NewEvent, Iterable[NewEvent]],
|
|
526
|
+
timeout: Optional[float] = None,
|
|
527
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
528
|
+
) -> int:
|
|
529
|
+
"""
|
|
530
|
+
Appends a new event or a sequence of new events to the named stream.
|
|
531
|
+
"""
|
|
532
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
533
|
+
if isinstance(events, NewEvent):
|
|
534
|
+
return self.streams.append(
|
|
535
|
+
stream_name=stream_name,
|
|
536
|
+
current_version=current_version,
|
|
537
|
+
events=[events],
|
|
538
|
+
timeout=timeout,
|
|
539
|
+
metadata=self._call_metadata,
|
|
540
|
+
credentials=credentials or self._call_credentials,
|
|
541
|
+
)
|
|
542
|
+
else:
|
|
543
|
+
return self.streams.batch_append(
|
|
544
|
+
stream_name=stream_name,
|
|
545
|
+
current_version=current_version,
|
|
546
|
+
events=events,
|
|
547
|
+
timeout=timeout,
|
|
548
|
+
metadata=self._call_metadata,
|
|
549
|
+
credentials=credentials or self._call_credentials,
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
@retrygrpc
|
|
553
|
+
@autoreconnect
|
|
554
|
+
def delete_stream(
|
|
555
|
+
self,
|
|
556
|
+
stream_name: str,
|
|
557
|
+
*,
|
|
558
|
+
current_version: Union[int, StreamState],
|
|
559
|
+
timeout: Optional[float] = None,
|
|
560
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
561
|
+
) -> None:
|
|
562
|
+
# Todo: Reconsider using current_version=None to indicate "stream exists"?
|
|
563
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
564
|
+
self.streams.delete(
|
|
565
|
+
stream_name=stream_name,
|
|
566
|
+
current_version=current_version,
|
|
567
|
+
timeout=timeout,
|
|
568
|
+
metadata=self._call_metadata,
|
|
569
|
+
credentials=credentials or self._call_credentials,
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
@retrygrpc
|
|
573
|
+
@autoreconnect
|
|
574
|
+
def tombstone_stream(
|
|
575
|
+
self,
|
|
576
|
+
stream_name: str,
|
|
577
|
+
*,
|
|
578
|
+
current_version: Union[int, StreamState],
|
|
579
|
+
timeout: Optional[float] = None,
|
|
580
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
581
|
+
) -> None:
|
|
582
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
583
|
+
self.streams.tombstone(
|
|
584
|
+
stream_name=stream_name,
|
|
585
|
+
current_version=current_version,
|
|
586
|
+
timeout=timeout,
|
|
587
|
+
metadata=self._call_metadata,
|
|
588
|
+
credentials=credentials or self._call_credentials,
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
@retrygrpc
|
|
592
|
+
@autoreconnect
|
|
593
|
+
def get_stream(
|
|
594
|
+
self,
|
|
595
|
+
stream_name: str,
|
|
596
|
+
*,
|
|
597
|
+
stream_position: Optional[int] = None,
|
|
598
|
+
backwards: bool = False,
|
|
599
|
+
resolve_links: bool = False,
|
|
600
|
+
limit: int = sys.maxsize,
|
|
601
|
+
timeout: Optional[float] = None,
|
|
602
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
603
|
+
) -> Sequence[RecordedEvent]:
|
|
604
|
+
"""
|
|
605
|
+
Returns a sequence of recorded events from the named stream.
|
|
606
|
+
"""
|
|
607
|
+
with self.read_stream(
|
|
608
|
+
stream_name=stream_name,
|
|
609
|
+
stream_position=stream_position,
|
|
610
|
+
backwards=backwards,
|
|
611
|
+
resolve_links=resolve_links,
|
|
612
|
+
limit=limit,
|
|
613
|
+
timeout=timeout,
|
|
614
|
+
credentials=credentials or self._call_credentials,
|
|
615
|
+
) as events:
|
|
616
|
+
return tuple(events)
|
|
617
|
+
|
|
618
|
+
def read_stream(
|
|
619
|
+
self,
|
|
620
|
+
stream_name: str,
|
|
621
|
+
*,
|
|
622
|
+
stream_position: Optional[int] = None,
|
|
623
|
+
backwards: bool = False,
|
|
624
|
+
resolve_links: bool = False,
|
|
625
|
+
limit: int = sys.maxsize,
|
|
626
|
+
timeout: Optional[float] = None,
|
|
627
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
628
|
+
) -> AbstractReadResponse:
|
|
629
|
+
"""
|
|
630
|
+
Reads recorded events from the named stream.
|
|
631
|
+
"""
|
|
632
|
+
return self.streams.read(
|
|
633
|
+
stream_name=stream_name,
|
|
634
|
+
stream_position=stream_position,
|
|
635
|
+
backwards=backwards,
|
|
636
|
+
resolve_links=resolve_links,
|
|
637
|
+
limit=limit,
|
|
638
|
+
timeout=timeout,
|
|
639
|
+
metadata=self._call_metadata,
|
|
640
|
+
credentials=credentials or self._call_credentials,
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
def read_all(
|
|
644
|
+
self,
|
|
645
|
+
*,
|
|
646
|
+
commit_position: Optional[int] = None,
|
|
647
|
+
backwards: bool = False,
|
|
648
|
+
resolve_links: bool = False,
|
|
649
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
650
|
+
filter_include: Sequence[str] = (),
|
|
651
|
+
filter_by_stream_name: bool = False,
|
|
652
|
+
limit: int = sys.maxsize,
|
|
653
|
+
timeout: Optional[float] = None,
|
|
654
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
655
|
+
) -> AbstractReadResponse:
|
|
656
|
+
"""
|
|
657
|
+
Reads recorded events in "all streams" in the database.
|
|
658
|
+
"""
|
|
659
|
+
return self.streams.read(
|
|
660
|
+
commit_position=commit_position,
|
|
661
|
+
backwards=backwards,
|
|
662
|
+
resolve_links=resolve_links,
|
|
663
|
+
filter_exclude=filter_exclude,
|
|
664
|
+
filter_include=filter_include,
|
|
665
|
+
filter_by_stream_name=filter_by_stream_name,
|
|
666
|
+
limit=limit,
|
|
667
|
+
timeout=timeout,
|
|
668
|
+
metadata=self._call_metadata,
|
|
669
|
+
credentials=credentials or self._call_credentials,
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
@retrygrpc
|
|
673
|
+
@autoreconnect
|
|
674
|
+
def get_current_version(
|
|
675
|
+
self,
|
|
676
|
+
stream_name: str,
|
|
677
|
+
*,
|
|
678
|
+
timeout: Optional[float] = None,
|
|
679
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
680
|
+
) -> Union[int, Literal[StreamState.NO_STREAM]]:
|
|
681
|
+
"""
|
|
682
|
+
Returns the current position of the end of a stream.
|
|
683
|
+
"""
|
|
684
|
+
try:
|
|
685
|
+
last_event = list(
|
|
686
|
+
self.streams.read(
|
|
687
|
+
stream_name=stream_name,
|
|
688
|
+
backwards=True,
|
|
689
|
+
limit=1,
|
|
690
|
+
timeout=timeout,
|
|
691
|
+
metadata=self._call_metadata,
|
|
692
|
+
credentials=credentials or self._call_credentials,
|
|
693
|
+
)
|
|
694
|
+
)[0]
|
|
695
|
+
except NotFound:
|
|
696
|
+
# StreamState.NO_STREAM is the correct "current version" both when appending
|
|
697
|
+
# to a stream that never existed and when appending to a stream that has
|
|
698
|
+
# been deleted (in this case of a deleted stream, the "current version"
|
|
699
|
+
# before deletion is also correct).
|
|
700
|
+
return StreamState.NO_STREAM
|
|
701
|
+
else:
|
|
702
|
+
return last_event.stream_position
|
|
703
|
+
|
|
704
|
+
@retrygrpc
|
|
705
|
+
@autoreconnect
|
|
706
|
+
def get_commit_position(
|
|
707
|
+
self,
|
|
708
|
+
*,
|
|
709
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
710
|
+
filter_include: Sequence[str] = (),
|
|
711
|
+
filter_by_stream_name: bool = False,
|
|
712
|
+
timeout: Optional[float] = None,
|
|
713
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
714
|
+
) -> int:
|
|
715
|
+
"""
|
|
716
|
+
Returns the current commit position of the database.
|
|
717
|
+
"""
|
|
718
|
+
recorded_events = self.streams.read(
|
|
719
|
+
backwards=True,
|
|
720
|
+
filter_exclude=filter_exclude,
|
|
721
|
+
filter_include=filter_include,
|
|
722
|
+
filter_by_stream_name=filter_by_stream_name,
|
|
723
|
+
limit=1,
|
|
724
|
+
timeout=timeout,
|
|
725
|
+
metadata=self._call_metadata,
|
|
726
|
+
credentials=credentials or self._call_credentials,
|
|
727
|
+
)
|
|
728
|
+
for ev in recorded_events:
|
|
729
|
+
assert ev.commit_position is not None
|
|
730
|
+
commit_position = ev.commit_position
|
|
731
|
+
break
|
|
732
|
+
else:
|
|
733
|
+
commit_position = 0
|
|
734
|
+
return commit_position
|
|
735
|
+
|
|
736
|
+
@retrygrpc
|
|
737
|
+
@autoreconnect
|
|
738
|
+
def get_stream_metadata(
|
|
739
|
+
self,
|
|
740
|
+
stream_name: str,
|
|
741
|
+
*,
|
|
742
|
+
timeout: Optional[float] = None,
|
|
743
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
744
|
+
) -> Tuple[Dict[str, Any], Union[int, Literal[StreamState.NO_STREAM]]]:
|
|
745
|
+
"""
|
|
746
|
+
Gets the stream metadata.
|
|
747
|
+
"""
|
|
748
|
+
metadata_stream_name = f"$${stream_name}"
|
|
749
|
+
try:
|
|
750
|
+
metadata_events = self.get_stream(
|
|
751
|
+
stream_name=metadata_stream_name,
|
|
752
|
+
backwards=True,
|
|
753
|
+
limit=1,
|
|
754
|
+
timeout=timeout,
|
|
755
|
+
credentials=credentials or self._call_credentials,
|
|
756
|
+
)
|
|
757
|
+
except NotFound:
|
|
758
|
+
return {}, StreamState.NO_STREAM
|
|
759
|
+
else:
|
|
760
|
+
metadata_event = metadata_events[0]
|
|
761
|
+
return json.loads(metadata_event.data), metadata_event.stream_position
|
|
762
|
+
|
|
763
|
+
def set_stream_metadata(
|
|
764
|
+
self,
|
|
765
|
+
stream_name: str,
|
|
766
|
+
*,
|
|
767
|
+
metadata: Dict[str, Any],
|
|
768
|
+
current_version: Union[int, StreamState] = StreamState.ANY,
|
|
769
|
+
timeout: Optional[float] = None,
|
|
770
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
771
|
+
) -> None:
|
|
772
|
+
"""
|
|
773
|
+
Sets the stream metadata.
|
|
774
|
+
"""
|
|
775
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
776
|
+
|
|
777
|
+
metadata_stream_name = f"$${stream_name}"
|
|
778
|
+
metadata_event = NewEvent(
|
|
779
|
+
type="$metadata",
|
|
780
|
+
data=json.dumps(metadata).encode("utf8"),
|
|
781
|
+
)
|
|
782
|
+
self.append_event(
|
|
783
|
+
stream_name=metadata_stream_name,
|
|
784
|
+
current_version=current_version,
|
|
785
|
+
event=metadata_event,
|
|
786
|
+
timeout=timeout,
|
|
787
|
+
credentials=credentials or self._call_credentials,
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
@retrygrpc
|
|
791
|
+
@autoreconnect
|
|
792
|
+
def subscribe_to_all(
|
|
793
|
+
self,
|
|
794
|
+
*,
|
|
795
|
+
commit_position: Optional[int] = None,
|
|
796
|
+
from_end: bool = False,
|
|
797
|
+
resolve_links: bool = False,
|
|
798
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
799
|
+
filter_include: Sequence[str] = (),
|
|
800
|
+
filter_by_stream_name: bool = False,
|
|
801
|
+
include_checkpoints: bool = False,
|
|
802
|
+
window_size: int = DEFAULT_WINDOW_SIZE,
|
|
803
|
+
checkpoint_interval_multiplier: int = DEFAULT_CHECKPOINT_INTERVAL_MULTIPLIER,
|
|
804
|
+
include_caught_up: bool = False,
|
|
805
|
+
timeout: Optional[float] = None,
|
|
806
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
807
|
+
) -> AbstractCatchupSubscription:
|
|
808
|
+
"""
|
|
809
|
+
Starts a catch-up subscription, from which all
|
|
810
|
+
recorded events in the database can be received.
|
|
811
|
+
"""
|
|
812
|
+
return self.streams.read(
|
|
813
|
+
commit_position=commit_position,
|
|
814
|
+
from_end=from_end,
|
|
815
|
+
resolve_links=resolve_links,
|
|
816
|
+
filter_exclude=filter_exclude,
|
|
817
|
+
filter_include=filter_include,
|
|
818
|
+
filter_by_stream_name=filter_by_stream_name,
|
|
819
|
+
subscribe=True,
|
|
820
|
+
include_checkpoints=include_checkpoints,
|
|
821
|
+
window_size=window_size,
|
|
822
|
+
checkpoint_interval_multiplier=checkpoint_interval_multiplier,
|
|
823
|
+
include_caught_up=include_caught_up,
|
|
824
|
+
timeout=timeout,
|
|
825
|
+
metadata=self._call_metadata,
|
|
826
|
+
credentials=credentials or self._call_credentials,
|
|
827
|
+
)
|
|
828
|
+
|
|
829
|
+
# @overload
|
|
830
|
+
# def subscribe_to_stream(
|
|
831
|
+
# self,
|
|
832
|
+
# stream_name: str,
|
|
833
|
+
# *,
|
|
834
|
+
# resolve_links: bool = False,
|
|
835
|
+
# include_caught_up: bool = False,
|
|
836
|
+
# timeout: Optional[float] = None,
|
|
837
|
+
# credentials: Optional[grpc.CallCredentials] = None,
|
|
838
|
+
# ) -> CatchupSubscription:
|
|
839
|
+
# """
|
|
840
|
+
# Signature to start catch-up subscription from the start of the stream.
|
|
841
|
+
# """
|
|
842
|
+
#
|
|
843
|
+
# @overload
|
|
844
|
+
# def subscribe_to_stream(
|
|
845
|
+
# self,
|
|
846
|
+
# stream_name: str,
|
|
847
|
+
# *,
|
|
848
|
+
# stream_position: int,
|
|
849
|
+
# resolve_links: bool = False,
|
|
850
|
+
# include_caught_up: bool = False,
|
|
851
|
+
# timeout: Optional[float] = None,
|
|
852
|
+
# credentials: Optional[grpc.CallCredentials] = None,
|
|
853
|
+
# ) -> CatchupSubscription:
|
|
854
|
+
# """
|
|
855
|
+
# Signature to start catch-up subscription from a particular stream position.
|
|
856
|
+
# """
|
|
857
|
+
#
|
|
858
|
+
# @overload
|
|
859
|
+
# def subscribe_to_stream(
|
|
860
|
+
# self,
|
|
861
|
+
# stream_name: str,
|
|
862
|
+
# *,
|
|
863
|
+
# from_end: Literal[True] = True,
|
|
864
|
+
# resolve_links: bool = False,
|
|
865
|
+
# include_caught_up: bool = False,
|
|
866
|
+
# timeout: Optional[float] = None,
|
|
867
|
+
# credentials: Optional[grpc.CallCredentials] = None,
|
|
868
|
+
# ) -> CatchupSubscription:
|
|
869
|
+
# """
|
|
870
|
+
# Signature to start catch-up subscription from the end of the stream.
|
|
871
|
+
# """
|
|
872
|
+
|
|
873
|
+
@retrygrpc
|
|
874
|
+
@autoreconnect
|
|
875
|
+
def subscribe_to_stream(
|
|
876
|
+
self,
|
|
877
|
+
stream_name: str,
|
|
878
|
+
*,
|
|
879
|
+
stream_position: Optional[int] = None,
|
|
880
|
+
from_end: bool = False,
|
|
881
|
+
resolve_links: bool = False,
|
|
882
|
+
include_caught_up: bool = False,
|
|
883
|
+
timeout: Optional[float] = None,
|
|
884
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
885
|
+
) -> AbstractCatchupSubscription:
|
|
886
|
+
"""
|
|
887
|
+
Starts a catch-up subscription from which
|
|
888
|
+
recorded events in a stream can be received.
|
|
889
|
+
"""
|
|
890
|
+
return self.streams.read(
|
|
891
|
+
stream_name=stream_name,
|
|
892
|
+
stream_position=stream_position,
|
|
893
|
+
from_end=from_end,
|
|
894
|
+
resolve_links=resolve_links,
|
|
895
|
+
subscribe=True,
|
|
896
|
+
include_caught_up=include_caught_up,
|
|
897
|
+
timeout=timeout,
|
|
898
|
+
metadata=self._call_metadata,
|
|
899
|
+
credentials=credentials or self._call_credentials,
|
|
900
|
+
)
|
|
901
|
+
|
|
902
|
+
@overload
|
|
903
|
+
def create_subscription_to_all(
|
|
904
|
+
self,
|
|
905
|
+
group_name: str,
|
|
906
|
+
*,
|
|
907
|
+
resolve_links: bool = False,
|
|
908
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
909
|
+
filter_include: Sequence[str] = (),
|
|
910
|
+
filter_by_stream_name: bool = False,
|
|
911
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
912
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
913
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
914
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
915
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
916
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
917
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
918
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
919
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
920
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
921
|
+
extra_statistics: bool = False,
|
|
922
|
+
timeout: Optional[float] = None,
|
|
923
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
924
|
+
) -> None:
|
|
925
|
+
"""
|
|
926
|
+
Signature for creating persistent subscription from start of database.
|
|
927
|
+
"""
|
|
928
|
+
|
|
929
|
+
@overload
|
|
930
|
+
def create_subscription_to_all(
|
|
931
|
+
self,
|
|
932
|
+
group_name: str,
|
|
933
|
+
*,
|
|
934
|
+
commit_position: int,
|
|
935
|
+
resolve_links: bool = False,
|
|
936
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
937
|
+
filter_include: Sequence[str] = (),
|
|
938
|
+
filter_by_stream_name: bool = False,
|
|
939
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
940
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
941
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
942
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
943
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
944
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
945
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
946
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
947
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
948
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
949
|
+
extra_statistics: bool = False,
|
|
950
|
+
timeout: Optional[float] = None,
|
|
951
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
952
|
+
) -> None:
|
|
953
|
+
"""
|
|
954
|
+
Signature for creating persistent subscription from a commit position.
|
|
955
|
+
"""
|
|
956
|
+
|
|
957
|
+
@overload
|
|
958
|
+
def create_subscription_to_all(
|
|
959
|
+
self,
|
|
960
|
+
group_name: str,
|
|
961
|
+
*,
|
|
962
|
+
from_end: bool = True,
|
|
963
|
+
resolve_links: bool = False,
|
|
964
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
965
|
+
filter_include: Sequence[str] = (),
|
|
966
|
+
filter_by_stream_name: bool = False,
|
|
967
|
+
window_size: int = DEFAULT_WINDOW_SIZE,
|
|
968
|
+
checkpoint_interval_multiplier: int = DEFAULT_CHECKPOINT_INTERVAL_MULTIPLIER,
|
|
969
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
970
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
971
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
972
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
973
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
974
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
975
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
976
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
977
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
978
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
979
|
+
extra_statistics: bool = False,
|
|
980
|
+
timeout: Optional[float] = None,
|
|
981
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
982
|
+
) -> None:
|
|
983
|
+
"""
|
|
984
|
+
Signature for creating persistent subscription from end of database.
|
|
985
|
+
"""
|
|
986
|
+
|
|
987
|
+
@retrygrpc
|
|
988
|
+
@autoreconnect
|
|
989
|
+
def create_subscription_to_all(
|
|
990
|
+
self,
|
|
991
|
+
group_name: str,
|
|
992
|
+
*,
|
|
993
|
+
from_end: bool = False,
|
|
994
|
+
commit_position: Optional[int] = None,
|
|
995
|
+
resolve_links: bool = False,
|
|
996
|
+
filter_exclude: Sequence[str] = DEFAULT_EXCLUDE_FILTER,
|
|
997
|
+
filter_include: Sequence[str] = (),
|
|
998
|
+
filter_by_stream_name: bool = False,
|
|
999
|
+
window_size: int = DEFAULT_WINDOW_SIZE,
|
|
1000
|
+
checkpoint_interval_multiplier: int = DEFAULT_CHECKPOINT_INTERVAL_MULTIPLIER,
|
|
1001
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
1002
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
1003
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
1004
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
1005
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
1006
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
1007
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
1008
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
1009
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
1010
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
1011
|
+
extra_statistics: bool = False,
|
|
1012
|
+
timeout: Optional[float] = None,
|
|
1013
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1014
|
+
) -> None:
|
|
1015
|
+
"""
|
|
1016
|
+
Creates a persistent subscription on all streams.
|
|
1017
|
+
"""
|
|
1018
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1019
|
+
|
|
1020
|
+
self.persistent_subscriptions.create(
|
|
1021
|
+
group_name=group_name,
|
|
1022
|
+
from_end=from_end,
|
|
1023
|
+
commit_position=commit_position,
|
|
1024
|
+
resolve_links=resolve_links,
|
|
1025
|
+
consumer_strategy=consumer_strategy,
|
|
1026
|
+
filter_exclude=filter_exclude,
|
|
1027
|
+
filter_include=filter_include,
|
|
1028
|
+
filter_by_stream_name=filter_by_stream_name,
|
|
1029
|
+
window_size=window_size,
|
|
1030
|
+
checkpoint_interval_multiplier=checkpoint_interval_multiplier,
|
|
1031
|
+
message_timeout=message_timeout,
|
|
1032
|
+
max_retry_count=max_retry_count,
|
|
1033
|
+
min_checkpoint_count=min_checkpoint_count,
|
|
1034
|
+
max_checkpoint_count=max_checkpoint_count,
|
|
1035
|
+
checkpoint_after=checkpoint_after,
|
|
1036
|
+
max_subscriber_count=max_subscriber_count,
|
|
1037
|
+
live_buffer_size=live_buffer_size,
|
|
1038
|
+
read_batch_size=read_batch_size,
|
|
1039
|
+
history_buffer_size=history_buffer_size,
|
|
1040
|
+
extra_statistics=extra_statistics,
|
|
1041
|
+
timeout=timeout,
|
|
1042
|
+
metadata=self._call_metadata,
|
|
1043
|
+
credentials=credentials or self._call_credentials,
|
|
1044
|
+
)
|
|
1045
|
+
|
|
1046
|
+
@overload
|
|
1047
|
+
def create_subscription_to_stream(
|
|
1048
|
+
self,
|
|
1049
|
+
group_name: str,
|
|
1050
|
+
stream_name: str,
|
|
1051
|
+
*,
|
|
1052
|
+
resolve_links: bool = False,
|
|
1053
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
1054
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
1055
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
1056
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
1057
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
1058
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
1059
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
1060
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
1061
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
1062
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
1063
|
+
extra_statistics: bool = False,
|
|
1064
|
+
timeout: Optional[float] = None,
|
|
1065
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1066
|
+
) -> None:
|
|
1067
|
+
"""
|
|
1068
|
+
Signature for creating stream subscription from start of stream.
|
|
1069
|
+
"""
|
|
1070
|
+
|
|
1071
|
+
@overload
|
|
1072
|
+
def create_subscription_to_stream(
|
|
1073
|
+
self,
|
|
1074
|
+
group_name: str,
|
|
1075
|
+
stream_name: str,
|
|
1076
|
+
*,
|
|
1077
|
+
stream_position: int,
|
|
1078
|
+
resolve_links: bool = False,
|
|
1079
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
1080
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
1081
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
1082
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
1083
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
1084
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
1085
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
1086
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
1087
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
1088
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
1089
|
+
extra_statistics: bool = False,
|
|
1090
|
+
timeout: Optional[float] = None,
|
|
1091
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1092
|
+
) -> None:
|
|
1093
|
+
"""
|
|
1094
|
+
Signature for creating stream subscription from stream position.
|
|
1095
|
+
"""
|
|
1096
|
+
|
|
1097
|
+
@overload
|
|
1098
|
+
def create_subscription_to_stream(
|
|
1099
|
+
self,
|
|
1100
|
+
group_name: str,
|
|
1101
|
+
stream_name: str,
|
|
1102
|
+
*,
|
|
1103
|
+
from_end: bool = True,
|
|
1104
|
+
resolve_links: bool = False,
|
|
1105
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
1106
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
1107
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
1108
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
1109
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
1110
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
1111
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
1112
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
1113
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
1114
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
1115
|
+
extra_statistics: bool = False,
|
|
1116
|
+
timeout: Optional[float] = None,
|
|
1117
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1118
|
+
) -> None:
|
|
1119
|
+
"""
|
|
1120
|
+
Signature for creating stream subscription from end of stream.
|
|
1121
|
+
"""
|
|
1122
|
+
|
|
1123
|
+
@retrygrpc
|
|
1124
|
+
@autoreconnect
|
|
1125
|
+
def create_subscription_to_stream(
|
|
1126
|
+
self,
|
|
1127
|
+
group_name: str,
|
|
1128
|
+
stream_name: str,
|
|
1129
|
+
*,
|
|
1130
|
+
from_end: bool = False,
|
|
1131
|
+
stream_position: Optional[int] = None,
|
|
1132
|
+
resolve_links: bool = False,
|
|
1133
|
+
consumer_strategy: ConsumerStrategy = "DispatchToSingle",
|
|
1134
|
+
message_timeout: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MESSAGE_TIMEOUT,
|
|
1135
|
+
max_retry_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_RETRY_COUNT,
|
|
1136
|
+
min_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MIN_CHECKPOINT_COUNT,
|
|
1137
|
+
max_checkpoint_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_CHECKPOINT_COUNT,
|
|
1138
|
+
checkpoint_after: float = DEFAULT_PERSISTENT_SUBSCRIPTION_CHECKPOINT_AFTER,
|
|
1139
|
+
max_subscriber_count: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_SUBSCRIBER_COUNT,
|
|
1140
|
+
live_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_LIVE_BUFFER_SIZE,
|
|
1141
|
+
read_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_READ_BATCH_SIZE,
|
|
1142
|
+
history_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_HISTORY_BUFFER_SIZE,
|
|
1143
|
+
extra_statistics: bool = False,
|
|
1144
|
+
timeout: Optional[float] = None,
|
|
1145
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1146
|
+
) -> None:
|
|
1147
|
+
"""
|
|
1148
|
+
Creates a persistent subscription on one stream.
|
|
1149
|
+
"""
|
|
1150
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1151
|
+
|
|
1152
|
+
self.persistent_subscriptions.create(
|
|
1153
|
+
group_name=group_name,
|
|
1154
|
+
stream_name=stream_name,
|
|
1155
|
+
from_end=from_end,
|
|
1156
|
+
stream_position=stream_position,
|
|
1157
|
+
resolve_links=resolve_links,
|
|
1158
|
+
consumer_strategy=consumer_strategy,
|
|
1159
|
+
message_timeout=message_timeout,
|
|
1160
|
+
max_retry_count=max_retry_count,
|
|
1161
|
+
min_checkpoint_count=min_checkpoint_count,
|
|
1162
|
+
max_checkpoint_count=max_checkpoint_count,
|
|
1163
|
+
checkpoint_after=checkpoint_after,
|
|
1164
|
+
max_subscriber_count=max_subscriber_count,
|
|
1165
|
+
live_buffer_size=live_buffer_size,
|
|
1166
|
+
read_batch_size=read_batch_size,
|
|
1167
|
+
history_buffer_size=history_buffer_size,
|
|
1168
|
+
extra_statistics=extra_statistics,
|
|
1169
|
+
timeout=timeout,
|
|
1170
|
+
metadata=self._call_metadata,
|
|
1171
|
+
credentials=credentials or self._call_credentials,
|
|
1172
|
+
)
|
|
1173
|
+
|
|
1174
|
+
@retrygrpc
|
|
1175
|
+
@autoreconnect
|
|
1176
|
+
def read_subscription_to_all(
|
|
1177
|
+
self,
|
|
1178
|
+
group_name: str,
|
|
1179
|
+
*,
|
|
1180
|
+
event_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_EVENT_BUFFER_SIZE,
|
|
1181
|
+
max_ack_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_BATCH_SIZE,
|
|
1182
|
+
max_ack_delay: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_DELAY,
|
|
1183
|
+
stopping_grace: float = DEFAULT_PERSISTENT_SUBSCRIPTION_STOPPING_GRACE,
|
|
1184
|
+
timeout: Optional[float] = None,
|
|
1185
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1186
|
+
) -> AbstractPersistentSubscription:
|
|
1187
|
+
"""
|
|
1188
|
+
Reads a persistent subscription on all streams.
|
|
1189
|
+
"""
|
|
1190
|
+
return self.persistent_subscriptions.read(
|
|
1191
|
+
group_name=group_name,
|
|
1192
|
+
event_buffer_size=event_buffer_size,
|
|
1193
|
+
max_ack_batch_size=max_ack_batch_size,
|
|
1194
|
+
max_ack_delay=max_ack_delay,
|
|
1195
|
+
stopping_grace=stopping_grace,
|
|
1196
|
+
timeout=timeout,
|
|
1197
|
+
metadata=self._call_metadata,
|
|
1198
|
+
credentials=credentials or self._call_credentials,
|
|
1199
|
+
)
|
|
1200
|
+
|
|
1201
|
+
@retrygrpc
|
|
1202
|
+
@autoreconnect
|
|
1203
|
+
def read_subscription_to_stream(
|
|
1204
|
+
self,
|
|
1205
|
+
group_name: str,
|
|
1206
|
+
stream_name: str,
|
|
1207
|
+
*,
|
|
1208
|
+
event_buffer_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_EVENT_BUFFER_SIZE,
|
|
1209
|
+
max_ack_batch_size: int = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_BATCH_SIZE,
|
|
1210
|
+
max_ack_delay: float = DEFAULT_PERSISTENT_SUBSCRIPTION_MAX_ACK_DELAY,
|
|
1211
|
+
stopping_grace: float = DEFAULT_PERSISTENT_SUBSCRIPTION_STOPPING_GRACE,
|
|
1212
|
+
timeout: Optional[float] = None,
|
|
1213
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1214
|
+
) -> AbstractPersistentSubscription:
|
|
1215
|
+
"""
|
|
1216
|
+
Reads a persistent subscription on one stream.
|
|
1217
|
+
"""
|
|
1218
|
+
return self.persistent_subscriptions.read(
|
|
1219
|
+
group_name=group_name,
|
|
1220
|
+
stream_name=stream_name,
|
|
1221
|
+
event_buffer_size=event_buffer_size,
|
|
1222
|
+
max_ack_batch_size=max_ack_batch_size,
|
|
1223
|
+
max_ack_delay=max_ack_delay,
|
|
1224
|
+
stopping_grace=stopping_grace,
|
|
1225
|
+
timeout=timeout,
|
|
1226
|
+
metadata=self._call_metadata,
|
|
1227
|
+
credentials=credentials or self._call_credentials,
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
@retrygrpc
|
|
1231
|
+
@autoreconnect
|
|
1232
|
+
def get_subscription_info(
|
|
1233
|
+
self,
|
|
1234
|
+
group_name: str,
|
|
1235
|
+
stream_name: Optional[str] = None,
|
|
1236
|
+
*,
|
|
1237
|
+
timeout: Optional[float] = None,
|
|
1238
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1239
|
+
) -> SubscriptionInfo:
|
|
1240
|
+
"""
|
|
1241
|
+
Gets info for a persistent subscription.
|
|
1242
|
+
"""
|
|
1243
|
+
return self.persistent_subscriptions.get_info(
|
|
1244
|
+
group_name=group_name,
|
|
1245
|
+
stream_name=stream_name,
|
|
1246
|
+
timeout=timeout,
|
|
1247
|
+
metadata=self._call_metadata,
|
|
1248
|
+
credentials=credentials or self._call_credentials,
|
|
1249
|
+
)
|
|
1250
|
+
|
|
1251
|
+
@retrygrpc
|
|
1252
|
+
@autoreconnect
|
|
1253
|
+
def list_subscriptions(
|
|
1254
|
+
self,
|
|
1255
|
+
*,
|
|
1256
|
+
timeout: Optional[float] = None,
|
|
1257
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1258
|
+
) -> Sequence[SubscriptionInfo]:
|
|
1259
|
+
"""
|
|
1260
|
+
Lists all persistent subscriptions.
|
|
1261
|
+
"""
|
|
1262
|
+
return self.persistent_subscriptions.list(
|
|
1263
|
+
timeout=timeout,
|
|
1264
|
+
metadata=self._call_metadata,
|
|
1265
|
+
credentials=credentials or self._call_credentials,
|
|
1266
|
+
)
|
|
1267
|
+
|
|
1268
|
+
@retrygrpc
|
|
1269
|
+
@autoreconnect
|
|
1270
|
+
def list_subscriptions_to_stream(
|
|
1271
|
+
self,
|
|
1272
|
+
stream_name: str,
|
|
1273
|
+
*,
|
|
1274
|
+
timeout: Optional[float] = None,
|
|
1275
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1276
|
+
) -> Sequence[SubscriptionInfo]:
|
|
1277
|
+
"""
|
|
1278
|
+
Lists persistent stream subscriptions.
|
|
1279
|
+
"""
|
|
1280
|
+
return self.persistent_subscriptions.list(
|
|
1281
|
+
stream_name=stream_name,
|
|
1282
|
+
timeout=timeout,
|
|
1283
|
+
metadata=self._call_metadata,
|
|
1284
|
+
credentials=credentials or self._call_credentials,
|
|
1285
|
+
)
|
|
1286
|
+
|
|
1287
|
+
@overload
|
|
1288
|
+
def update_subscription_to_all(
|
|
1289
|
+
self,
|
|
1290
|
+
group_name: str,
|
|
1291
|
+
*,
|
|
1292
|
+
resolve_links: Optional[bool] = None,
|
|
1293
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1294
|
+
message_timeout: Optional[float] = None,
|
|
1295
|
+
max_retry_count: Optional[int] = None,
|
|
1296
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1297
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1298
|
+
checkpoint_after: Optional[float] = None,
|
|
1299
|
+
max_subscriber_count: Optional[int] = None,
|
|
1300
|
+
live_buffer_size: Optional[int] = None,
|
|
1301
|
+
read_batch_size: Optional[int] = None,
|
|
1302
|
+
history_buffer_size: Optional[int] = None,
|
|
1303
|
+
extra_statistics: Optional[bool] = None,
|
|
1304
|
+
timeout: Optional[float] = None,
|
|
1305
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1306
|
+
) -> None:
|
|
1307
|
+
"""
|
|
1308
|
+
Signature for updating subscription to run from same position.
|
|
1309
|
+
"""
|
|
1310
|
+
|
|
1311
|
+
@overload
|
|
1312
|
+
def update_subscription_to_all(
|
|
1313
|
+
self,
|
|
1314
|
+
group_name: str,
|
|
1315
|
+
*,
|
|
1316
|
+
from_end: Literal[False],
|
|
1317
|
+
resolve_links: Optional[bool] = None,
|
|
1318
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1319
|
+
message_timeout: Optional[float] = None,
|
|
1320
|
+
max_retry_count: Optional[int] = None,
|
|
1321
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1322
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1323
|
+
checkpoint_after: Optional[float] = None,
|
|
1324
|
+
max_subscriber_count: Optional[int] = None,
|
|
1325
|
+
live_buffer_size: Optional[int] = None,
|
|
1326
|
+
read_batch_size: Optional[int] = None,
|
|
1327
|
+
history_buffer_size: Optional[int] = None,
|
|
1328
|
+
extra_statistics: Optional[bool] = None,
|
|
1329
|
+
timeout: Optional[float] = None,
|
|
1330
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1331
|
+
) -> None:
|
|
1332
|
+
"""
|
|
1333
|
+
Signature for updating subscription to run from start of database.
|
|
1334
|
+
"""
|
|
1335
|
+
|
|
1336
|
+
@overload
|
|
1337
|
+
def update_subscription_to_all(
|
|
1338
|
+
self,
|
|
1339
|
+
group_name: str,
|
|
1340
|
+
*,
|
|
1341
|
+
from_end: Literal[True],
|
|
1342
|
+
resolve_links: Optional[bool] = None,
|
|
1343
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1344
|
+
message_timeout: Optional[float] = None,
|
|
1345
|
+
max_retry_count: Optional[int] = None,
|
|
1346
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1347
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1348
|
+
checkpoint_after: Optional[float] = None,
|
|
1349
|
+
max_subscriber_count: Optional[int] = None,
|
|
1350
|
+
live_buffer_size: Optional[int] = None,
|
|
1351
|
+
read_batch_size: Optional[int] = None,
|
|
1352
|
+
history_buffer_size: Optional[int] = None,
|
|
1353
|
+
extra_statistics: Optional[bool] = None,
|
|
1354
|
+
timeout: Optional[float] = None,
|
|
1355
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1356
|
+
) -> None:
|
|
1357
|
+
"""
|
|
1358
|
+
Signature for updating subscription to run from end of database.
|
|
1359
|
+
"""
|
|
1360
|
+
|
|
1361
|
+
@overload
|
|
1362
|
+
def update_subscription_to_all(
|
|
1363
|
+
self,
|
|
1364
|
+
group_name: str,
|
|
1365
|
+
*,
|
|
1366
|
+
commit_position: int,
|
|
1367
|
+
resolve_links: Optional[bool] = None,
|
|
1368
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1369
|
+
message_timeout: Optional[float] = None,
|
|
1370
|
+
max_retry_count: Optional[int] = None,
|
|
1371
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1372
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1373
|
+
checkpoint_after: Optional[float] = None,
|
|
1374
|
+
max_subscriber_count: Optional[int] = None,
|
|
1375
|
+
live_buffer_size: Optional[int] = None,
|
|
1376
|
+
read_batch_size: Optional[int] = None,
|
|
1377
|
+
history_buffer_size: Optional[int] = None,
|
|
1378
|
+
extra_statistics: Optional[bool] = None,
|
|
1379
|
+
timeout: Optional[float] = None,
|
|
1380
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1381
|
+
) -> None:
|
|
1382
|
+
"""
|
|
1383
|
+
Signature for updating persistent subscription to run from a commit position.
|
|
1384
|
+
"""
|
|
1385
|
+
|
|
1386
|
+
@retrygrpc
|
|
1387
|
+
@autoreconnect
|
|
1388
|
+
def update_subscription_to_all(
|
|
1389
|
+
self,
|
|
1390
|
+
group_name: str,
|
|
1391
|
+
*,
|
|
1392
|
+
from_end: Optional[bool] = None,
|
|
1393
|
+
commit_position: Optional[int] = None,
|
|
1394
|
+
resolve_links: Optional[bool] = None,
|
|
1395
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1396
|
+
message_timeout: Optional[float] = None,
|
|
1397
|
+
max_retry_count: Optional[int] = None,
|
|
1398
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1399
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1400
|
+
checkpoint_after: Optional[float] = None,
|
|
1401
|
+
max_subscriber_count: Optional[int] = None,
|
|
1402
|
+
live_buffer_size: Optional[int] = None,
|
|
1403
|
+
read_batch_size: Optional[int] = None,
|
|
1404
|
+
history_buffer_size: Optional[int] = None,
|
|
1405
|
+
extra_statistics: Optional[bool] = None,
|
|
1406
|
+
timeout: Optional[float] = None,
|
|
1407
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1408
|
+
) -> None:
|
|
1409
|
+
"""
|
|
1410
|
+
Updates a persistent subscription on all streams.
|
|
1411
|
+
"""
|
|
1412
|
+
|
|
1413
|
+
info = self.get_subscription_info(
|
|
1414
|
+
group_name=group_name, timeout=timeout, credentials=credentials
|
|
1415
|
+
)
|
|
1416
|
+
kwargs = info.update_all_kwargs(
|
|
1417
|
+
from_end=from_end,
|
|
1418
|
+
commit_position=commit_position,
|
|
1419
|
+
resolve_links=resolve_links,
|
|
1420
|
+
consumer_strategy=consumer_strategy,
|
|
1421
|
+
message_timeout=message_timeout,
|
|
1422
|
+
max_retry_count=max_retry_count,
|
|
1423
|
+
min_checkpoint_count=min_checkpoint_count,
|
|
1424
|
+
max_checkpoint_count=max_checkpoint_count,
|
|
1425
|
+
checkpoint_after=checkpoint_after,
|
|
1426
|
+
max_subscriber_count=max_subscriber_count,
|
|
1427
|
+
live_buffer_size=live_buffer_size,
|
|
1428
|
+
read_batch_size=read_batch_size,
|
|
1429
|
+
history_buffer_size=history_buffer_size,
|
|
1430
|
+
extra_statistics=extra_statistics,
|
|
1431
|
+
)
|
|
1432
|
+
|
|
1433
|
+
self.persistent_subscriptions.update(
|
|
1434
|
+
group_name=group_name,
|
|
1435
|
+
**kwargs,
|
|
1436
|
+
timeout=timeout if timeout is not None else self._default_deadline,
|
|
1437
|
+
metadata=self._call_metadata,
|
|
1438
|
+
credentials=credentials or self._call_credentials,
|
|
1439
|
+
)
|
|
1440
|
+
|
|
1441
|
+
@overload
|
|
1442
|
+
def update_subscription_to_stream(
|
|
1443
|
+
self,
|
|
1444
|
+
group_name: str,
|
|
1445
|
+
stream_name: str,
|
|
1446
|
+
*,
|
|
1447
|
+
resolve_links: Optional[bool] = None,
|
|
1448
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1449
|
+
message_timeout: Optional[float] = None,
|
|
1450
|
+
max_retry_count: Optional[int] = None,
|
|
1451
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1452
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1453
|
+
checkpoint_after: Optional[float] = None,
|
|
1454
|
+
max_subscriber_count: Optional[int] = None,
|
|
1455
|
+
live_buffer_size: Optional[int] = None,
|
|
1456
|
+
read_batch_size: Optional[int] = None,
|
|
1457
|
+
history_buffer_size: Optional[int] = None,
|
|
1458
|
+
extra_statistics: Optional[bool] = None,
|
|
1459
|
+
timeout: Optional[float] = None,
|
|
1460
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1461
|
+
) -> None:
|
|
1462
|
+
"""
|
|
1463
|
+
Signature for updating subscription to run from same stream position.
|
|
1464
|
+
"""
|
|
1465
|
+
|
|
1466
|
+
@overload
|
|
1467
|
+
def update_subscription_to_stream(
|
|
1468
|
+
self,
|
|
1469
|
+
group_name: str,
|
|
1470
|
+
stream_name: str,
|
|
1471
|
+
*,
|
|
1472
|
+
from_end: Literal[False],
|
|
1473
|
+
resolve_links: Optional[bool] = None,
|
|
1474
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1475
|
+
message_timeout: Optional[float] = None,
|
|
1476
|
+
max_retry_count: Optional[int] = None,
|
|
1477
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1478
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1479
|
+
checkpoint_after: Optional[float] = None,
|
|
1480
|
+
max_subscriber_count: Optional[int] = None,
|
|
1481
|
+
live_buffer_size: Optional[int] = None,
|
|
1482
|
+
read_batch_size: Optional[int] = None,
|
|
1483
|
+
history_buffer_size: Optional[int] = None,
|
|
1484
|
+
extra_statistics: Optional[bool] = None,
|
|
1485
|
+
timeout: Optional[float] = None,
|
|
1486
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1487
|
+
) -> None:
|
|
1488
|
+
"""
|
|
1489
|
+
Signature for updating subscription to run from start of stream.
|
|
1490
|
+
"""
|
|
1491
|
+
|
|
1492
|
+
@overload
|
|
1493
|
+
def update_subscription_to_stream(
|
|
1494
|
+
self,
|
|
1495
|
+
group_name: str,
|
|
1496
|
+
stream_name: str,
|
|
1497
|
+
*,
|
|
1498
|
+
from_end: Literal[True],
|
|
1499
|
+
resolve_links: Optional[bool] = None,
|
|
1500
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1501
|
+
message_timeout: Optional[float] = None,
|
|
1502
|
+
max_retry_count: Optional[int] = None,
|
|
1503
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1504
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1505
|
+
checkpoint_after: Optional[float] = None,
|
|
1506
|
+
max_subscriber_count: Optional[int] = None,
|
|
1507
|
+
live_buffer_size: Optional[int] = None,
|
|
1508
|
+
read_batch_size: Optional[int] = None,
|
|
1509
|
+
history_buffer_size: Optional[int] = None,
|
|
1510
|
+
extra_statistics: Optional[bool] = None,
|
|
1511
|
+
timeout: Optional[float] = None,
|
|
1512
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1513
|
+
) -> None:
|
|
1514
|
+
"""
|
|
1515
|
+
Signature for updating subscription to run from end of stream.
|
|
1516
|
+
"""
|
|
1517
|
+
|
|
1518
|
+
@overload
|
|
1519
|
+
def update_subscription_to_stream(
|
|
1520
|
+
self,
|
|
1521
|
+
group_name: str,
|
|
1522
|
+
stream_name: str,
|
|
1523
|
+
*,
|
|
1524
|
+
stream_position: int,
|
|
1525
|
+
resolve_links: Optional[bool] = None,
|
|
1526
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1527
|
+
message_timeout: Optional[float] = None,
|
|
1528
|
+
max_retry_count: Optional[int] = None,
|
|
1529
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1530
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1531
|
+
checkpoint_after: Optional[float] = None,
|
|
1532
|
+
max_subscriber_count: Optional[int] = None,
|
|
1533
|
+
live_buffer_size: Optional[int] = None,
|
|
1534
|
+
read_batch_size: Optional[int] = None,
|
|
1535
|
+
history_buffer_size: Optional[int] = None,
|
|
1536
|
+
extra_statistics: Optional[bool] = None,
|
|
1537
|
+
timeout: Optional[float] = None,
|
|
1538
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1539
|
+
) -> None:
|
|
1540
|
+
"""
|
|
1541
|
+
Signature for updating subscription to run from stream position.
|
|
1542
|
+
"""
|
|
1543
|
+
|
|
1544
|
+
@retrygrpc
|
|
1545
|
+
@autoreconnect
|
|
1546
|
+
def update_subscription_to_stream(
|
|
1547
|
+
self,
|
|
1548
|
+
group_name: str,
|
|
1549
|
+
stream_name: str,
|
|
1550
|
+
*,
|
|
1551
|
+
from_end: Optional[bool] = None,
|
|
1552
|
+
stream_position: Optional[int] = None,
|
|
1553
|
+
resolve_links: Optional[bool] = None,
|
|
1554
|
+
consumer_strategy: Optional[ConsumerStrategy] = None,
|
|
1555
|
+
message_timeout: Optional[float] = None,
|
|
1556
|
+
max_retry_count: Optional[int] = None,
|
|
1557
|
+
min_checkpoint_count: Optional[int] = None,
|
|
1558
|
+
max_checkpoint_count: Optional[int] = None,
|
|
1559
|
+
checkpoint_after: Optional[float] = None,
|
|
1560
|
+
max_subscriber_count: Optional[int] = None,
|
|
1561
|
+
live_buffer_size: Optional[int] = None,
|
|
1562
|
+
read_batch_size: Optional[int] = None,
|
|
1563
|
+
history_buffer_size: Optional[int] = None,
|
|
1564
|
+
extra_statistics: Optional[bool] = None,
|
|
1565
|
+
timeout: Optional[float] = None,
|
|
1566
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1567
|
+
) -> None:
|
|
1568
|
+
"""
|
|
1569
|
+
Updates a persistent subscription on one stream.
|
|
1570
|
+
"""
|
|
1571
|
+
|
|
1572
|
+
info = self.get_subscription_info(
|
|
1573
|
+
group_name=group_name,
|
|
1574
|
+
stream_name=stream_name,
|
|
1575
|
+
timeout=timeout,
|
|
1576
|
+
credentials=credentials,
|
|
1577
|
+
)
|
|
1578
|
+
kwargs = info.update_stream_kwargs(
|
|
1579
|
+
from_end=from_end,
|
|
1580
|
+
stream_position=stream_position,
|
|
1581
|
+
resolve_links=resolve_links,
|
|
1582
|
+
consumer_strategy=consumer_strategy,
|
|
1583
|
+
message_timeout=message_timeout,
|
|
1584
|
+
max_retry_count=max_retry_count,
|
|
1585
|
+
min_checkpoint_count=min_checkpoint_count,
|
|
1586
|
+
max_checkpoint_count=max_checkpoint_count,
|
|
1587
|
+
checkpoint_after=checkpoint_after,
|
|
1588
|
+
max_subscriber_count=max_subscriber_count,
|
|
1589
|
+
live_buffer_size=live_buffer_size,
|
|
1590
|
+
read_batch_size=read_batch_size,
|
|
1591
|
+
history_buffer_size=history_buffer_size,
|
|
1592
|
+
extra_statistics=extra_statistics,
|
|
1593
|
+
)
|
|
1594
|
+
|
|
1595
|
+
self.persistent_subscriptions.update(
|
|
1596
|
+
group_name=group_name,
|
|
1597
|
+
stream_name=stream_name,
|
|
1598
|
+
**kwargs,
|
|
1599
|
+
timeout=timeout if timeout is not None else self._default_deadline,
|
|
1600
|
+
metadata=self._call_metadata,
|
|
1601
|
+
credentials=credentials or self._call_credentials,
|
|
1602
|
+
)
|
|
1603
|
+
|
|
1604
|
+
@retrygrpc
|
|
1605
|
+
@autoreconnect
|
|
1606
|
+
def replay_parked_events(
|
|
1607
|
+
self,
|
|
1608
|
+
group_name: str,
|
|
1609
|
+
stream_name: Optional[str] = None,
|
|
1610
|
+
*,
|
|
1611
|
+
timeout: Optional[float] = None,
|
|
1612
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1613
|
+
) -> None:
|
|
1614
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1615
|
+
|
|
1616
|
+
self.persistent_subscriptions.replay_parked(
|
|
1617
|
+
group_name=group_name,
|
|
1618
|
+
stream_name=stream_name,
|
|
1619
|
+
timeout=timeout,
|
|
1620
|
+
metadata=self._call_metadata,
|
|
1621
|
+
credentials=credentials or self._call_credentials,
|
|
1622
|
+
)
|
|
1623
|
+
|
|
1624
|
+
@retrygrpc
|
|
1625
|
+
@autoreconnect
|
|
1626
|
+
def delete_subscription(
|
|
1627
|
+
self,
|
|
1628
|
+
group_name: str,
|
|
1629
|
+
stream_name: Optional[str] = None,
|
|
1630
|
+
*,
|
|
1631
|
+
timeout: Optional[float] = None,
|
|
1632
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1633
|
+
) -> None:
|
|
1634
|
+
"""
|
|
1635
|
+
Deletes a persistent subscription.
|
|
1636
|
+
"""
|
|
1637
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1638
|
+
|
|
1639
|
+
self.persistent_subscriptions.delete(
|
|
1640
|
+
group_name=group_name,
|
|
1641
|
+
stream_name=stream_name,
|
|
1642
|
+
timeout=timeout,
|
|
1643
|
+
metadata=self._call_metadata,
|
|
1644
|
+
credentials=credentials or self._call_credentials,
|
|
1645
|
+
)
|
|
1646
|
+
|
|
1647
|
+
@retrygrpc
|
|
1648
|
+
@autoreconnect
|
|
1649
|
+
def read_gossip(
|
|
1650
|
+
self,
|
|
1651
|
+
*,
|
|
1652
|
+
timeout: Optional[float] = None,
|
|
1653
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1654
|
+
) -> Sequence[ClusterMember]:
|
|
1655
|
+
timeout = (
|
|
1656
|
+
timeout
|
|
1657
|
+
if timeout is not None
|
|
1658
|
+
else self.connection_spec.options.GossipTimeout
|
|
1659
|
+
)
|
|
1660
|
+
return self.gossip.read(
|
|
1661
|
+
timeout=timeout,
|
|
1662
|
+
metadata=self._call_metadata,
|
|
1663
|
+
credentials=credentials or self._call_credentials,
|
|
1664
|
+
)
|
|
1665
|
+
|
|
1666
|
+
@retrygrpc
|
|
1667
|
+
@autoreconnect
|
|
1668
|
+
def create_projection(
|
|
1669
|
+
self,
|
|
1670
|
+
*,
|
|
1671
|
+
name: str,
|
|
1672
|
+
query: str,
|
|
1673
|
+
emit_enabled: bool = False,
|
|
1674
|
+
track_emitted_streams: bool = False,
|
|
1675
|
+
timeout: Optional[float] = None,
|
|
1676
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1677
|
+
) -> None:
|
|
1678
|
+
"""
|
|
1679
|
+
Creates a projection.
|
|
1680
|
+
"""
|
|
1681
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1682
|
+
|
|
1683
|
+
self.projections.create(
|
|
1684
|
+
query=query,
|
|
1685
|
+
name=name,
|
|
1686
|
+
emit_enabled=emit_enabled,
|
|
1687
|
+
track_emitted_streams=track_emitted_streams,
|
|
1688
|
+
timeout=timeout,
|
|
1689
|
+
metadata=self._call_metadata,
|
|
1690
|
+
credentials=credentials or self._call_credentials,
|
|
1691
|
+
)
|
|
1692
|
+
|
|
1693
|
+
@retrygrpc
|
|
1694
|
+
@autoreconnect
|
|
1695
|
+
def update_projection(
|
|
1696
|
+
self,
|
|
1697
|
+
name: str,
|
|
1698
|
+
*,
|
|
1699
|
+
query: str,
|
|
1700
|
+
emit_enabled: bool = False,
|
|
1701
|
+
timeout: Optional[float] = None,
|
|
1702
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1703
|
+
) -> None:
|
|
1704
|
+
"""
|
|
1705
|
+
Updates a projection.
|
|
1706
|
+
"""
|
|
1707
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1708
|
+
|
|
1709
|
+
self.projections.update(
|
|
1710
|
+
name=name,
|
|
1711
|
+
query=query,
|
|
1712
|
+
emit_enabled=emit_enabled,
|
|
1713
|
+
timeout=timeout,
|
|
1714
|
+
metadata=self._call_metadata,
|
|
1715
|
+
credentials=credentials or self._call_credentials,
|
|
1716
|
+
)
|
|
1717
|
+
|
|
1718
|
+
@retrygrpc
|
|
1719
|
+
@autoreconnect
|
|
1720
|
+
def delete_projection(
|
|
1721
|
+
self,
|
|
1722
|
+
name: str,
|
|
1723
|
+
*,
|
|
1724
|
+
delete_emitted_streams: bool = False,
|
|
1725
|
+
delete_state_stream: bool = False,
|
|
1726
|
+
delete_checkpoint_stream: bool = False,
|
|
1727
|
+
timeout: Optional[float] = None,
|
|
1728
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1729
|
+
) -> None:
|
|
1730
|
+
"""
|
|
1731
|
+
Deletes a projection.
|
|
1732
|
+
"""
|
|
1733
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1734
|
+
|
|
1735
|
+
self.projections.delete(
|
|
1736
|
+
name=name,
|
|
1737
|
+
delete_emitted_streams=delete_emitted_streams,
|
|
1738
|
+
delete_state_stream=delete_state_stream,
|
|
1739
|
+
delete_checkpoint_stream=delete_checkpoint_stream,
|
|
1740
|
+
timeout=timeout,
|
|
1741
|
+
metadata=self._call_metadata,
|
|
1742
|
+
credentials=credentials or self._call_credentials,
|
|
1743
|
+
)
|
|
1744
|
+
|
|
1745
|
+
@retrygrpc
|
|
1746
|
+
@autoreconnect
|
|
1747
|
+
def get_projection_statistics(
|
|
1748
|
+
self,
|
|
1749
|
+
*,
|
|
1750
|
+
name: str,
|
|
1751
|
+
timeout: Optional[float] = None,
|
|
1752
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1753
|
+
) -> ProjectionStatistics:
|
|
1754
|
+
"""
|
|
1755
|
+
Gets projection statistics.
|
|
1756
|
+
"""
|
|
1757
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1758
|
+
|
|
1759
|
+
return self.projections.get_statistics(
|
|
1760
|
+
name=name,
|
|
1761
|
+
timeout=timeout,
|
|
1762
|
+
metadata=self._call_metadata,
|
|
1763
|
+
credentials=credentials or self._call_credentials,
|
|
1764
|
+
)
|
|
1765
|
+
|
|
1766
|
+
@retrygrpc
|
|
1767
|
+
@autoreconnect
|
|
1768
|
+
def disable_projection(
|
|
1769
|
+
self,
|
|
1770
|
+
name: str,
|
|
1771
|
+
*,
|
|
1772
|
+
timeout: Optional[float] = None,
|
|
1773
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1774
|
+
) -> None:
|
|
1775
|
+
"""
|
|
1776
|
+
Disables a projection.
|
|
1777
|
+
"""
|
|
1778
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1779
|
+
|
|
1780
|
+
self.projections.disable(
|
|
1781
|
+
name=name,
|
|
1782
|
+
write_checkpoint=True,
|
|
1783
|
+
timeout=timeout,
|
|
1784
|
+
metadata=self._call_metadata,
|
|
1785
|
+
credentials=credentials or self._call_credentials,
|
|
1786
|
+
)
|
|
1787
|
+
|
|
1788
|
+
@retrygrpc
|
|
1789
|
+
@autoreconnect
|
|
1790
|
+
def enable_projection(
|
|
1791
|
+
self,
|
|
1792
|
+
name: str,
|
|
1793
|
+
*,
|
|
1794
|
+
timeout: Optional[float] = None,
|
|
1795
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1796
|
+
) -> None:
|
|
1797
|
+
"""
|
|
1798
|
+
Disables a projection.
|
|
1799
|
+
"""
|
|
1800
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1801
|
+
|
|
1802
|
+
self.projections.enable(
|
|
1803
|
+
name=name,
|
|
1804
|
+
timeout=timeout,
|
|
1805
|
+
metadata=self._call_metadata,
|
|
1806
|
+
credentials=credentials or self._call_credentials,
|
|
1807
|
+
)
|
|
1808
|
+
|
|
1809
|
+
@retrygrpc
|
|
1810
|
+
@autoreconnect
|
|
1811
|
+
def reset_projection(
|
|
1812
|
+
self,
|
|
1813
|
+
name: str,
|
|
1814
|
+
*,
|
|
1815
|
+
timeout: Optional[float] = None,
|
|
1816
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1817
|
+
) -> None:
|
|
1818
|
+
"""
|
|
1819
|
+
Resets a projection.
|
|
1820
|
+
"""
|
|
1821
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1822
|
+
|
|
1823
|
+
self.projections.reset(
|
|
1824
|
+
name=name,
|
|
1825
|
+
write_checkpoint=True,
|
|
1826
|
+
timeout=timeout,
|
|
1827
|
+
metadata=self._call_metadata,
|
|
1828
|
+
credentials=credentials or self._call_credentials,
|
|
1829
|
+
)
|
|
1830
|
+
|
|
1831
|
+
@retrygrpc
|
|
1832
|
+
@autoreconnect
|
|
1833
|
+
def get_projection_state(
|
|
1834
|
+
self,
|
|
1835
|
+
name: str,
|
|
1836
|
+
*,
|
|
1837
|
+
timeout: Optional[float] = None,
|
|
1838
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1839
|
+
) -> ProjectionState:
|
|
1840
|
+
"""
|
|
1841
|
+
Gets projection state.
|
|
1842
|
+
"""
|
|
1843
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1844
|
+
|
|
1845
|
+
return self.projections.get_state(
|
|
1846
|
+
name=name,
|
|
1847
|
+
partition="",
|
|
1848
|
+
timeout=timeout,
|
|
1849
|
+
metadata=self._call_metadata,
|
|
1850
|
+
credentials=credentials or self._call_credentials,
|
|
1851
|
+
)
|
|
1852
|
+
|
|
1853
|
+
# @retrygrpc
|
|
1854
|
+
# @autoreconnect
|
|
1855
|
+
# def get_projection_result(
|
|
1856
|
+
# self,
|
|
1857
|
+
# name: str,
|
|
1858
|
+
# *,
|
|
1859
|
+
# timeout: Optional[float] = None,
|
|
1860
|
+
# credentials: Optional[grpc.CallCredentials] = None,
|
|
1861
|
+
# ) -> ProjectionResult:
|
|
1862
|
+
# """
|
|
1863
|
+
# Gets projection result.
|
|
1864
|
+
# """
|
|
1865
|
+
# timeout = timeout if timeout is not None else self._default_deadline
|
|
1866
|
+
#
|
|
1867
|
+
# return self.projections.get_result(
|
|
1868
|
+
# name=name,
|
|
1869
|
+
# partition="",
|
|
1870
|
+
# timeout=timeout,
|
|
1871
|
+
# metadata=self._call_metadata,
|
|
1872
|
+
# credentials=credentials or self._call_credentials,
|
|
1873
|
+
# )
|
|
1874
|
+
|
|
1875
|
+
@retrygrpc
|
|
1876
|
+
@autoreconnect
|
|
1877
|
+
def restart_projections_subsystem(
|
|
1878
|
+
self,
|
|
1879
|
+
*,
|
|
1880
|
+
timeout: Optional[float] = None,
|
|
1881
|
+
credentials: Optional[grpc.CallCredentials] = None,
|
|
1882
|
+
) -> None:
|
|
1883
|
+
"""
|
|
1884
|
+
Restarts projections subsystem.
|
|
1885
|
+
"""
|
|
1886
|
+
timeout = timeout if timeout is not None else self._default_deadline
|
|
1887
|
+
|
|
1888
|
+
return self.projections.restart_subsystem(
|
|
1889
|
+
timeout=timeout,
|
|
1890
|
+
metadata=self._call_metadata,
|
|
1891
|
+
credentials=credentials or self._call_credentials,
|
|
1892
|
+
)
|
|
1893
|
+
|
|
1894
|
+
def close(self) -> None:
|
|
1895
|
+
"""
|
|
1896
|
+
Closes the gRPC channel.
|
|
1897
|
+
"""
|
|
1898
|
+
if not self._is_closed:
|
|
1899
|
+
try:
|
|
1900
|
+
esdb_connection = self._connection
|
|
1901
|
+
except AttributeError:
|
|
1902
|
+
pass
|
|
1903
|
+
else:
|
|
1904
|
+
esdb_connection.close()
|
|
1905
|
+
self._is_closed = True
|
|
1906
|
+
|
|
1907
|
+
def __enter__(self) -> KurrentDBClient:
|
|
1908
|
+
return self
|
|
1909
|
+
|
|
1910
|
+
def __exit__(self, *args: Any, **kwargs: Any) -> None:
|
|
1911
|
+
self.close()
|
|
1912
|
+
|
|
1913
|
+
def __del__(self) -> None:
|
|
1914
|
+
self.close()
|