temporal-flowrensic-python-sdk 0.6.63__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.
- temporal_flowrensic/__init__.py +2 -0
- temporal_flowrensic/_calls.py +185 -0
- temporal_flowrensic/_ci.py +56 -0
- temporal_flowrensic/_deploy.py +65 -0
- temporal_flowrensic/_gen/flowrensic/v1/activity_metrics_pb2.py +76 -0
- temporal_flowrensic/_gen/flowrensic/v1/activity_metrics_pb2.pyi +301 -0
- temporal_flowrensic/_gen/flowrensic/v1/catalog_pb2.py +60 -0
- temporal_flowrensic/_gen/flowrensic/v1/catalog_pb2.pyi +127 -0
- temporal_flowrensic/_gen/flowrensic/v1/catch_up_pb2.py +42 -0
- temporal_flowrensic/_gen/flowrensic/v1/catch_up_pb2.pyi +71 -0
- temporal_flowrensic/_gen/flowrensic/v1/client_calls_pb2.py +49 -0
- temporal_flowrensic/_gen/flowrensic/v1/client_calls_pb2.pyi +90 -0
- temporal_flowrensic/_gen/flowrensic/v1/cost_pb2.py +52 -0
- temporal_flowrensic/_gen/flowrensic/v1/cost_pb2.pyi +107 -0
- temporal_flowrensic/_gen/flowrensic/v1/deploy_pb2.py +51 -0
- temporal_flowrensic/_gen/flowrensic/v1/deploy_pb2.pyi +92 -0
- temporal_flowrensic/_gen/flowrensic/v1/ephemeral_run_pb2.py +107 -0
- temporal_flowrensic/_gen/flowrensic/v1/ephemeral_run_pb2.pyi +344 -0
- temporal_flowrensic/_gen/flowrensic/v1/finding_pb2.py +76 -0
- temporal_flowrensic/_gen/flowrensic/v1/finding_pb2.pyi +371 -0
- temporal_flowrensic/_gen/flowrensic/v1/job_pb2.py +46 -0
- temporal_flowrensic/_gen/flowrensic/v1/job_pb2.pyi +51 -0
- temporal_flowrensic/_gen/flowrensic/v1/load_pb2.py +51 -0
- temporal_flowrensic/_gen/flowrensic/v1/load_pb2.pyi +118 -0
- temporal_flowrensic/_gen/flowrensic/v1/page_pb2.py +38 -0
- temporal_flowrensic/_gen/flowrensic/v1/page_pb2.pyi +23 -0
- temporal_flowrensic/_gen/flowrensic/v1/remediation_pb2.py +60 -0
- temporal_flowrensic/_gen/flowrensic/v1/remediation_pb2.pyi +157 -0
- temporal_flowrensic/_gen/flowrensic/v1/replay_pb2.py +84 -0
- temporal_flowrensic/_gen/flowrensic/v1/replay_pb2.pyi +309 -0
- temporal_flowrensic/_gen/flowrensic/v1/server_config_pb2.py +48 -0
- temporal_flowrensic/_gen/flowrensic/v1/server_config_pb2.pyi +97 -0
- temporal_flowrensic/_gen/flowrensic/v1/services_connect.py +3621 -0
- temporal_flowrensic/_gen/flowrensic/v1/services_pb2.py +60 -0
- temporal_flowrensic/_gen/flowrensic/v1/services_pb2.pyi +20 -0
- temporal_flowrensic/_gen/flowrensic/v1/stored_data_pb2.py +43 -0
- temporal_flowrensic/_gen/flowrensic/v1/stored_data_pb2.pyi +50 -0
- temporal_flowrensic/_gen/flowrensic/v1/workflow_history_pb2.py +47 -0
- temporal_flowrensic/_gen/flowrensic/v1/workflow_history_pb2.pyi +102 -0
- temporal_flowrensic/_gen/flowrensic/v1/workflow_types_pb2.py +55 -0
- temporal_flowrensic/_gen/flowrensic/v1/workflow_types_pb2.pyi +197 -0
- temporal_flowrensic/_names.py +42 -0
- temporal_flowrensic/_queries.py +61 -0
- temporal_flowrensic/_replay.py +378 -0
- temporal_flowrensic/_sink.py +574 -0
- temporal_flowrensic/_telemetry.py +559 -0
- temporal_flowrensic/activity.py +136 -0
- temporal_flowrensic/client.py +166 -0
- temporal_flowrensic/py.typed +0 -0
- temporal_flowrensic/workflow.py +103 -0
- temporal_flowrensic_python_sdk-0.6.63.dist-info/METADATA +74 -0
- temporal_flowrensic_python_sdk-0.6.63.dist-info/RECORD +54 -0
- temporal_flowrensic_python_sdk-0.6.63.dist-info/WHEEL +4 -0
- temporal_flowrensic_python_sdk-0.6.63.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""The client interceptor: every query and signal of a temporalio Client that
|
|
2
|
+
raises is sent to Flowrensic, through the record buffer."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import time
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
|
|
9
|
+
import temporalio.client
|
|
10
|
+
import temporalio.service
|
|
11
|
+
from temporalio.service import RPCError, RPCStatusCode
|
|
12
|
+
|
|
13
|
+
from temporal_flowrensic._gen.flowrensic.v1.client_calls_pb2 import (
|
|
14
|
+
CLIENT_CALL_OUTCOME_FAILED,
|
|
15
|
+
CLIENT_CALL_OUTCOME_TIMED_OUT,
|
|
16
|
+
ClientCall,
|
|
17
|
+
IngestClientCallsRequest,
|
|
18
|
+
)
|
|
19
|
+
from temporal_flowrensic._sink import (
|
|
20
|
+
DEFAULT_BATCH_SIZE,
|
|
21
|
+
DEFAULT_FLUSH_INTERVAL,
|
|
22
|
+
DEFAULT_MAX_BATCH_SIZE,
|
|
23
|
+
DEFAULT_MAX_WAITING,
|
|
24
|
+
DEFAULT_MAX_WAITING_BYTES,
|
|
25
|
+
DEFAULT_TIMEOUT_MS,
|
|
26
|
+
BufferTarget,
|
|
27
|
+
RecordSink,
|
|
28
|
+
SendId,
|
|
29
|
+
SinkCounts,
|
|
30
|
+
ingest_client_sync,
|
|
31
|
+
client_headers,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = ["ClientInterceptor"]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# The error type Flowrensic knows a query by that a worker answered with an
|
|
38
|
+
# error, the name the TypeScript client gives it. The Python client raises
|
|
39
|
+
# WorkflowQueryFailedError for the same case.
|
|
40
|
+
_ANSWERED_QUERY_ERROR = "QueryNotRegisteredError"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _error_type(err: BaseException) -> str:
|
|
44
|
+
if isinstance(err, temporalio.client.WorkflowQueryFailedError):
|
|
45
|
+
return _ANSWERED_QUERY_ERROR
|
|
46
|
+
return type(err).__name__
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _timed_out(err: BaseException) -> bool:
|
|
50
|
+
"""Whether the call ended on its deadline: deadline exceeded, or cancelled by the server."""
|
|
51
|
+
return isinstance(err, RPCError) and err.status in (RPCStatusCode.DEADLINE_EXCEEDED, RPCStatusCode.CANCELLED)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class _CallTarget(BufferTarget[ClientCall]):
|
|
55
|
+
def __init__(self, server_base_url: str, headers: dict[str, str]) -> None:
|
|
56
|
+
self._ingest = ingest_client_sync(server_base_url)
|
|
57
|
+
self._headers = headers
|
|
58
|
+
|
|
59
|
+
def send(self, records: list[ClientCall], timeout_ms: int, id: SendId) -> None:
|
|
60
|
+
self._ingest.ingest_client_calls(
|
|
61
|
+
IngestClientCallsRequest(calls=records, sender=id.sender, send_number=id.send_number),
|
|
62
|
+
headers=self._headers,
|
|
63
|
+
timeout_ms=max(1, timeout_ms),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# The namespace a temporalio Client talks to when it is given none.
|
|
68
|
+
_DEFAULT_NAMESPACE = "default"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ClientInterceptor(temporalio.client.Interceptor, temporalio.client.Plugin):
|
|
72
|
+
"""Put in Client.connect(plugins=[...]). Every query and signal that
|
|
73
|
+
raises is sent to Flowrensic with its name, the workflow it was for and
|
|
74
|
+
whether it ended on its deadline. A call that works is not sent. The calls
|
|
75
|
+
wait in a buffer and leave in batches, as the attempts of the worker do,
|
|
76
|
+
so sending never changes what the caller gets or how long it waits. Call
|
|
77
|
+
close before the process ends, so the calls still waiting are sent.
|
|
78
|
+
|
|
79
|
+
As a client plugin it reads the namespace of the client and puts itself in
|
|
80
|
+
the interceptors of the client, so each call is sent under the namespace
|
|
81
|
+
the client talks to. current_env, env_access_key and current_ephemeral_run
|
|
82
|
+
go in their headers on every send. Times are in seconds."""
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
server_base_url: str,
|
|
87
|
+
*,
|
|
88
|
+
current_env: str = "",
|
|
89
|
+
env_access_key: str = "",
|
|
90
|
+
current_ephemeral_run: str = "",
|
|
91
|
+
batch_size: int = DEFAULT_BATCH_SIZE,
|
|
92
|
+
flush_interval: float = DEFAULT_FLUSH_INTERVAL,
|
|
93
|
+
timeout_ms: int = DEFAULT_TIMEOUT_MS,
|
|
94
|
+
max_waiting: int = DEFAULT_MAX_WAITING,
|
|
95
|
+
max_batch_size: int = DEFAULT_MAX_BATCH_SIZE,
|
|
96
|
+
max_waiting_bytes: int = DEFAULT_MAX_WAITING_BYTES,
|
|
97
|
+
) -> None:
|
|
98
|
+
if not server_base_url:
|
|
99
|
+
raise ValueError("flowrensic: server_base_url is required")
|
|
100
|
+
self._namespace = _DEFAULT_NAMESPACE
|
|
101
|
+
self._next_plugin: Optional[temporalio.client.Plugin] = None
|
|
102
|
+
self._buffer: RecordSink[ClientCall] = RecordSink(
|
|
103
|
+
_CallTarget(server_base_url, client_headers(current_env, env_access_key, current_ephemeral_run)),
|
|
104
|
+
batch_size=batch_size,
|
|
105
|
+
flush_interval=flush_interval,
|
|
106
|
+
timeout_ms=timeout_ms,
|
|
107
|
+
max_waiting=max_waiting,
|
|
108
|
+
max_batch_size=max_batch_size,
|
|
109
|
+
max_waiting_bytes=max_waiting_bytes,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def intercept_client(self, next: temporalio.client.OutboundInterceptor) -> temporalio.client.OutboundInterceptor:
|
|
113
|
+
return _ClientOutbound(next, self)
|
|
114
|
+
|
|
115
|
+
def init_client_plugin(self, next: temporalio.client.Plugin) -> None:
|
|
116
|
+
"""Keeps the next plugin, for the temporalio versions that chain them."""
|
|
117
|
+
self._next_plugin = next
|
|
118
|
+
|
|
119
|
+
def configure_client(self, config: Any) -> Any:
|
|
120
|
+
"""Reads the namespace of the client and adds this interceptor to its interceptors."""
|
|
121
|
+
self._namespace = config.get("namespace") or _DEFAULT_NAMESPACE
|
|
122
|
+
interceptors = list(config.get("interceptors") or [])
|
|
123
|
+
if not any(one is self for one in interceptors):
|
|
124
|
+
interceptors.append(self)
|
|
125
|
+
config["interceptors"] = interceptors
|
|
126
|
+
if self._next_plugin is not None:
|
|
127
|
+
return self._next_plugin.configure_client(config)
|
|
128
|
+
return config
|
|
129
|
+
|
|
130
|
+
async def connect_service_client(self, config: Any, next: Any = None) -> Any:
|
|
131
|
+
"""Connects as the next plugin or temporalio would, unchanged."""
|
|
132
|
+
if next is not None:
|
|
133
|
+
return await next(config)
|
|
134
|
+
if self._next_plugin is not None:
|
|
135
|
+
return await self._next_plugin.connect_service_client(config)
|
|
136
|
+
return await temporalio.service.ServiceClient.connect(config)
|
|
137
|
+
|
|
138
|
+
async def flush(self) -> None:
|
|
139
|
+
"""Sends what waits and waits for it to land."""
|
|
140
|
+
await self._buffer.flush()
|
|
141
|
+
|
|
142
|
+
async def close(self) -> None:
|
|
143
|
+
"""Sends what waits and stops."""
|
|
144
|
+
await self._buffer.close()
|
|
145
|
+
|
|
146
|
+
def counts(self) -> SinkCounts:
|
|
147
|
+
"""What the buffer lost and holds."""
|
|
148
|
+
return self._buffer.counts()
|
|
149
|
+
|
|
150
|
+
def _record(self, kind: str, name: str, workflow_id: str, run_id: Optional[str], err: BaseException) -> None:
|
|
151
|
+
"""Records a call that raised, and never raises itself."""
|
|
152
|
+
try:
|
|
153
|
+
call = ClientCall(
|
|
154
|
+
namespace=self._namespace,
|
|
155
|
+
workflow_id=workflow_id,
|
|
156
|
+
run_id=run_id or "",
|
|
157
|
+
kind=kind,
|
|
158
|
+
name=name,
|
|
159
|
+
outcome=CLIENT_CALL_OUTCOME_TIMED_OUT if _timed_out(err) else CLIENT_CALL_OUTCOME_FAILED,
|
|
160
|
+
error_type=_error_type(err),
|
|
161
|
+
)
|
|
162
|
+
call.ended_at.FromNanoseconds(int(time.time() * 1_000_000_000))
|
|
163
|
+
self._buffer.record(call)
|
|
164
|
+
except Exception: # noqa: BLE001
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class _ClientOutbound(temporalio.client.OutboundInterceptor):
|
|
169
|
+
def __init__(self, next: temporalio.client.OutboundInterceptor, owner: ClientInterceptor) -> None:
|
|
170
|
+
super().__init__(next)
|
|
171
|
+
self._owner = owner
|
|
172
|
+
|
|
173
|
+
async def query_workflow(self, input: temporalio.client.QueryWorkflowInput) -> Any:
|
|
174
|
+
try:
|
|
175
|
+
return await super().query_workflow(input)
|
|
176
|
+
except Exception as err:
|
|
177
|
+
self._owner._record("query", input.query, input.id, input.run_id, err)
|
|
178
|
+
raise
|
|
179
|
+
|
|
180
|
+
async def signal_workflow(self, input: temporalio.client.SignalWorkflowInput) -> None:
|
|
181
|
+
try:
|
|
182
|
+
await super().signal_workflow(input)
|
|
183
|
+
except Exception as err:
|
|
184
|
+
self._owner._record("signal", input.signal, input.id, input.run_id, err)
|
|
185
|
+
raise
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""What the CI side of the SDK shares: the error a call that has to fail
|
|
2
|
+
raises, and the message that says Flowrensic could not be reached or what it
|
|
3
|
+
answered."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
from connectrpc.code import Code
|
|
10
|
+
from connectrpc.errors import ConnectError
|
|
11
|
+
|
|
12
|
+
__all__ = ["CIError", "ci_error", "ci_failure", "not_reached"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CIError(Exception):
|
|
16
|
+
"""A CI call to Flowrensic that failed. Its text says that Flowrensic
|
|
17
|
+
could not be reached in time, or what it answered. code is the Connect code
|
|
18
|
+
Flowrensic answered with, None when it was not reached."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, message: str, code: Optional[Code] = None) -> None:
|
|
21
|
+
super().__init__(message)
|
|
22
|
+
self.message = message
|
|
23
|
+
self.code = code
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def not_reached(error: BaseException) -> bool:
|
|
27
|
+
"""Whether a call failed because nothing answered in time or no connection
|
|
28
|
+
could be made. The client raises a transport error, such as a refused
|
|
29
|
+
connection, as a ConnectError raised from that error, while an answer of
|
|
30
|
+
Flowrensic carries no error under it."""
|
|
31
|
+
if not isinstance(error, ConnectError):
|
|
32
|
+
return True
|
|
33
|
+
if error.code in (Code.DEADLINE_EXCEEDED, Code.CANCELED):
|
|
34
|
+
return True
|
|
35
|
+
return error.__cause__ is not None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _seconds(timeout_ms: int) -> str:
|
|
39
|
+
return f"{timeout_ms / 1000:g}"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def ci_failure(what: str, server_base_url: str, timeout_ms: int, error: BaseException) -> str:
|
|
43
|
+
"""The message a CI call stops with: that Flowrensic could not be reached
|
|
44
|
+
in time, or what it answered, the code in brackets as Connect writes it and
|
|
45
|
+
the message. what names the call, such as deploy report."""
|
|
46
|
+
if not_reached(error):
|
|
47
|
+
cause = error.message if isinstance(error, ConnectError) else str(error)
|
|
48
|
+
return f"{what}: Flowrensic at {server_base_url} could not be reached within {_seconds(timeout_ms)} seconds: {cause}"
|
|
49
|
+
assert isinstance(error, ConnectError)
|
|
50
|
+
return f"{what}: Flowrensic at {server_base_url} answered [{error.code.value}] {error.message}"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def ci_error(what: str, server_base_url: str, timeout_ms: int, error: BaseException) -> CIError:
|
|
54
|
+
"""The error a CI call that has to fail raises, with the message of ci_failure."""
|
|
55
|
+
code = None if not_reached(error) or not isinstance(error, ConnectError) else error.code
|
|
56
|
+
return CIError(ci_failure(what, server_base_url, timeout_ms, error), code)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""The deploy stage report a CI job sends, with a time limit, so it never hangs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Optional, Sequence
|
|
7
|
+
|
|
8
|
+
from temporal_flowrensic._ci import ci_error, ci_failure
|
|
9
|
+
from temporal_flowrensic._gen.flowrensic.v1.deploy_pb2 import IngestDeployStageRequest
|
|
10
|
+
from temporal_flowrensic._gen.flowrensic.v1.services_connect import IngestServiceClient
|
|
11
|
+
from temporal_flowrensic._sink import client_headers
|
|
12
|
+
|
|
13
|
+
__all__ = ["DeployStageResult", "report_deploy_stage"]
|
|
14
|
+
|
|
15
|
+
_DEPLOY_REPORT_TIMEOUT_MS = 10_000
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class DeployStageResult:
|
|
20
|
+
"""What a deploy report did."""
|
|
21
|
+
|
|
22
|
+
sent: bool
|
|
23
|
+
"""Whether Flowrensic took the write."""
|
|
24
|
+
message: str
|
|
25
|
+
"""What happened, in one line, for the CI log."""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def report_deploy_stage(
|
|
29
|
+
*,
|
|
30
|
+
server_base_url: str,
|
|
31
|
+
env_access_key: str,
|
|
32
|
+
deploy_id: str,
|
|
33
|
+
current_env: str,
|
|
34
|
+
stage: str,
|
|
35
|
+
current_ephemeral_run: str = "",
|
|
36
|
+
declared_stages: Optional[Sequence[str]] = None,
|
|
37
|
+
rolling_out_version: str = "",
|
|
38
|
+
outcome: str = "",
|
|
39
|
+
timeout_ms: int = _DEPLOY_REPORT_TIMEOUT_MS,
|
|
40
|
+
fail_on_error: bool = False,
|
|
41
|
+
) -> DeployStageResult:
|
|
42
|
+
"""Sends one stage of a deploy to Flowrensic: initiated, started, replay,
|
|
43
|
+
testsStarted, testsDone or finished. The report has a time limit of
|
|
44
|
+
timeout_ms milliseconds, 10000 by default. A report that fails returns
|
|
45
|
+
sent False and a message that says Flowrensic could not be reached or what
|
|
46
|
+
it answered, so the deploy goes on; with fail_on_error it raises CIError instead.
|
|
47
|
+
current_env, env_access_key and current_ephemeral_run go in their headers."""
|
|
48
|
+
try:
|
|
49
|
+
async with IngestServiceClient(server_base_url.rstrip("/"), send_compression=None) as ingest:
|
|
50
|
+
await ingest.ingest_deploy_stage(
|
|
51
|
+
IngestDeployStageRequest(
|
|
52
|
+
deploy_id=deploy_id,
|
|
53
|
+
stage=stage,
|
|
54
|
+
declared_stages=list(declared_stages or []),
|
|
55
|
+
rolling_out_version=rolling_out_version,
|
|
56
|
+
outcome=outcome,
|
|
57
|
+
),
|
|
58
|
+
headers=client_headers(current_env, env_access_key, current_ephemeral_run),
|
|
59
|
+
timeout_ms=max(1, timeout_ms),
|
|
60
|
+
)
|
|
61
|
+
except Exception as error: # noqa: BLE001
|
|
62
|
+
if fail_on_error:
|
|
63
|
+
raise ci_error("deploy report", server_base_url, timeout_ms, error) from error
|
|
64
|
+
return DeployStageResult(False, ci_failure("deploy report", server_base_url, timeout_ms, error))
|
|
65
|
+
return DeployStageResult(True, f"deploy report: Flowrensic at {server_base_url} took the stage {stage} of {deploy_id}")
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: flowrensic/v1/activity_metrics.proto
|
|
5
|
+
# Protobuf Python Version: 6.31.1
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
|
+
1,
|
|
17
|
+
'',
|
|
18
|
+
'flowrensic/v1/activity_metrics.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from temporal_flowrensic._gen.flowrensic.v1 import page_pb2 as flowrensic_dot_v1_dot_page__pb2
|
|
26
|
+
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$flowrensic/v1/activity_metrics.proto\x12\rflowrensic.v1\x1a\x18\x66lowrensic/v1/page.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xbf\x06\n\x0f\x41\x63tivityAttempt\x12\x1c\n\tnamespace\x18\x15 \x01(\tR\tnamespace\x12#\n\rworkflow_type\x18\x02 \x01(\tR\x0cworkflowType\x12\x32\n\x15workflow_execution_id\x18\x03 \x01(\tR\x13workflowExecutionId\x12\x17\n\x07run_key\x18\x04 \x01(\tR\x06runKey\x12#\n\ractivity_type\x18\x05 \x01(\tR\x0c\x61\x63tivityType\x12\x1f\n\x0b\x61\x63tivity_id\x18\x06 \x01(\tR\nactivityId\x12\x18\n\x07\x61ttempt\x18\x07 \x01(\x05R\x07\x61ttempt\x12\x1d\n\ntask_queue\x18\x08 \x01(\tR\ttaskQueue\x12\x30\n\x07outcome\x18\t \x01(\x0e\x32\x16.flowrensic.v1.OutcomeR\x07outcome\x12\x1d\n\nerror_type\x18\n \x01(\tR\terrorType\x12\x39\n\nstarted_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartedAt\x12\x35\n\x08\x65nded_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x65ndedAt\x12\x1f\n\x0b\x64uration_ms\x18\r \x01(\x03R\ndurationMs\x12\x10\n\x03\x65nv\x18\x0e \x01(\tR\x03\x65nv\x12#\n\rephemeral_run\x18\x0f \x01(\tR\x0c\x65phemeralRun\x12\x18\n\x07version\x18\x10 \x01(\tR\x07version\x12\x38\n\x19start_to_close_timeout_ms\x18\x11 \x01(\x03R\x15startToCloseTimeoutMs\x12)\n\x10maximum_attempts\x18\x12 \x01(\x05R\x0fmaximumAttempts\x12\x30\n\x14heartbeat_timeout_ms\x18\x13 \x01(\x03R\x12heartbeatTimeoutMs\x12=\n\x0cscheduled_at\x18\x14 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x0bscheduledAtJ\x04\x08\x01\x10\x02R\x0cnamespace_id\"\x96\x06\n\rActivityStats\x12!\n\x0cnamespace_id\x18\x01 \x01(\tR\x0bnamespaceId\x12\x10\n\x03\x65nv\x18\x02 \x01(\tR\x03\x65nv\x12#\n\rworkflow_type\x18\x03 \x01(\tR\x0cworkflowType\x12#\n\ractivity_type\x18\x04 \x01(\tR\x0c\x61\x63tivityType\x12\x38\n\x19start_to_close_timeout_ms\x18\x13 \x01(\x03R\x15startToCloseTimeoutMs\x12)\n\x10maximum_attempts\x18\x14 \x01(\x05R\x0fmaximumAttempts\x12\x1e\n\nexecutions\x18\x05 \x01(\x05R\nexecutions\x12\x1a\n\x08\x61ttempts\x18\x06 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07retries\x18\x07 \x01(\x05R\x07retries\x12\x1c\n\tcompleted\x18\x08 \x01(\x05R\tcompleted\x12\x16\n\x06\x66\x61iled\x18\t \x01(\x05R\x06\x66\x61iled\x12\x1b\n\ttimed_out\x18\n \x01(\x05R\x08timedOut\x12\x1a\n\x08\x63\x61nceled\x18\x0b \x01(\x05R\x08\x63\x61nceled\x12M\n\x0b\x65rror_types\x18\x0c \x03(\x0b\x32,.flowrensic.v1.ActivityStats.ErrorTypesEntryR\nerrorTypes\x12\x15\n\x06p50_ms\x18\r \x01(\x03R\x05p50Ms\x12\x15\n\x06p95_ms\x18\x0e \x01(\x03R\x05p95Ms\x12\x15\n\x06p99_ms\x18\x0f \x01(\x03R\x05p99Ms\x12\x15\n\x06max_ms\x18\x10 \x01(\x03R\x05maxMs\x12\x39\n\nfirst_seen\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tfirstSeen\x12\x37\n\tlast_seen\x18\x12 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08lastSeen\x1a=\n\x0f\x45rrorTypesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\x05R\x05value:\x02\x38\x01\"\x89\x02\n\x1bIngestActivityEventsRequest\x12\x36\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x1e.flowrensic.v1.ActivityAttemptR\x06\x65vents\x12\x1b\n\tworker_id\x18\x02 \x01(\tR\x08workerId\x12;\n\x07reports\x18\x03 \x03(\x0b\x32!.flowrensic.v1.WorkerBufferReportR\x07reports\x12\x16\n\x06sender\x18\x04 \x01(\tR\x06sender\x12\x1f\n\x0bsend_number\x18\x05 \x01(\x03R\nsendNumber\x12\x1f\n\x0bworker_name\x18\x06 \x01(\tR\nworkerName\"\xa0\x01\n\x12WorkerBufferReport\x12\x10\n\x03\x65nv\x18\x01 \x01(\tR\x03\x65nv\x12\'\n\x0frecords_dropped\x18\x02 \x01(\x03R\x0erecordsDropped\x12&\n\x0fsends_timed_out\x18\x03 \x01(\x03R\rsendsTimedOut\x12\'\n\x0frecords_waiting\x18\x04 \x01(\x03R\x0erecordsWaiting\":\n\x1cIngestActivityEventsResponse\x12\x1a\n\x08\x61\x63\x63\x65pted\x18\x01 \x01(\x05R\x08\x61\x63\x63\x65pted\"\xc3\x05\n\x0bWorkflowRun\x12\x32\n\x15workflow_execution_id\x18\x01 \x01(\tR\x13workflowExecutionId\x12\x17\n\x07run_key\x18\x02 \x01(\tR\x06runKey\x12#\n\rworkflow_type\x18\x03 \x01(\tR\x0cworkflowType\x12!\n\x0cnamespace_id\x18\x04 \x01(\tR\x0bnamespaceId\x12\x10\n\x03\x65nv\x18\x05 \x01(\tR\x03\x65nv\x12\x1e\n\nactivities\x18\x06 \x01(\x05R\nactivities\x12\x1a\n\x08\x61ttempts\x18\x07 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07retries\x18\x08 \x01(\x05R\x07retries\x12\x16\n\x06\x66\x61iled\x18\t \x01(\x05R\x06\x66\x61iled\x12\x39\n\nstarted_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartedAt\x12\x37\n\tlast_seen\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08lastSeen\x12#\n\rephemeral_run\x18\x0c \x01(\tR\x0c\x65phemeralRun\x12\x1b\n\tdeploy_id\x18\r \x01(\tR\x08\x64\x65ployId\x12!\n\x0c\x64\x65ploy_stage\x18\x0e \x01(\tR\x0b\x64\x65ployStage\x12\x18\n\x07version\x18\x0f \x01(\tR\x07version\x12%\n\x0ehistory_length\x18\x10 \x01(\x05R\rhistoryLength\x12)\n\x10updates_accepted\x18\x11 \x01(\x05R\x0fupdatesAccepted\x12\'\n\x0fupdates_refused\x18\x12 \x01(\x05R\x0eupdatesRefused\x12\x31\n\x14\x63onsecutive_refusals\x18\x13 \x01(\x05R\x13\x63onsecutiveRefusals\"\xc0\x01\n\x0fListRunsRequest\x12#\n\rnamespace_ids\x18\x01 \x03(\tR\x0cnamespaceIds\x12\x10\n\x03\x65nv\x18\x02 \x01(\tR\x03\x65nv\x12#\n\rworkflow_type\x18\x03 \x01(\tR\x0cworkflowType\x12.\n\x04page\x18\x06 \x01(\x0b\x32\x1a.flowrensic.v1.PageRequestR\x04pageJ\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06R\tpage_sizeR\npage_token\"\x8a\x01\n\x10ListRunsResponse\x12.\n\x04runs\x18\x01 \x03(\x0b\x32\x1a.flowrensic.v1.WorkflowRunR\x04runs\x12/\n\x04page\x18\x03 \x01(\x0b\x32\x1b.flowrensic.v1.PageResponseR\x04pageJ\x04\x08\x02\x10\x03R\x0fnext_page_token\"\xbf\x02\n\x0c\x45ngineMetric\x12\x1b\n\tserver_id\x18\x01 \x01(\tR\x08serverId\x12\x10\n\x03\x65nv\x18\x02 \x01(\tR\x03\x65nv\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12?\n\x06labels\x18\x04 \x03(\x0b\x32\'.flowrensic.v1.EngineMetric.LabelsEntryR\x06labels\x12\x14\n\x05value\x18\x05 \x01(\x01R\x05value\x12\x39\n\nscraped_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tscrapedAt\x12\x1f\n\x0bmetric_type\x18\x07 \x01(\tR\nmetricType\x1a\x39\n\x0bLabelsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x86\x01\n\x14\x45ngineMetricsRequest\x12\x1d\n\nserver_ids\x18\x01 \x03(\tR\tserverIds\x12\x1f\n\x0bname_prefix\x18\x02 \x01(\tR\nnamePrefix\x12.\n\x04page\x18\x03 \x01(\x0b\x32\x1a.flowrensic.v1.PageRequestR\x04page\"\x7f\n\x15\x45ngineMetricsResponse\x12\x35\n\x07metrics\x18\x01 \x03(\x0b\x32\x1b.flowrensic.v1.EngineMetricR\x07metrics\x12/\n\x04page\x18\x02 \x01(\x0b\x32\x1b.flowrensic.v1.PageResponseR\x04page\"<\n\x17UpdateRejectionsRequest\x12!\n\x0cnamespace_id\x18\x01 \x01(\tR\x0bnamespaceId\"\x98\x01\n\x18UpdateRejectionsResponse\x12!\n\x0cnamespace_id\x18\x01 \x01(\tR\x0bnamespaceId\x12\x1e\n\nrejections\x18\x02 \x01(\x01R\nrejections\x12\x39\n\nscraped_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tscrapedAt\"\xab\x02\n\x14\x41\x63tivityStatsRequest\x12#\n\rnamespace_ids\x18\x01 \x03(\tR\x0cnamespaceIds\x12\x10\n\x03\x65nv\x18\x02 \x01(\tR\x03\x65nv\x12#\n\rworkflow_type\x18\x03 \x01(\tR\x0cworkflowType\x12#\n\ractivity_type\x18\x04 \x01(\tR\x0c\x61\x63tivityType\x12\x30\n\x05since\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x05since\x12\x30\n\x05until\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x05until\x12.\n\x04page\x18\x07 \x01(\x0b\x32\x1a.flowrensic.v1.PageRequestR\x04page\"|\n\x15\x41\x63tivityStatsResponse\x12\x32\n\x05stats\x18\x01 \x03(\x0b\x32\x1c.flowrensic.v1.ActivityStatsR\x05stats\x12/\n\x04page\x18\x02 \x01(\x0b\x32\x1b.flowrensic.v1.PageResponseR\x04page*z\n\x07Outcome\x12\x17\n\x13OUTCOME_UNSPECIFIED\x10\x00\x12\x15\n\x11OUTCOME_COMPLETED\x10\x01\x12\x12\n\x0eOUTCOME_FAILED\x10\x02\x12\x15\n\x11OUTCOME_TIMED_OUT\x10\x03\x12\x14\n\x10OUTCOME_CANCELED\x10\x04\x62\x06proto3')
|
|
30
|
+
|
|
31
|
+
_globals = globals()
|
|
32
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
33
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flowrensic.v1.activity_metrics_pb2', _globals)
|
|
34
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
35
|
+
DESCRIPTOR._loaded_options = None
|
|
36
|
+
_globals['_ACTIVITYSTATS_ERRORTYPESENTRY']._loaded_options = None
|
|
37
|
+
_globals['_ACTIVITYSTATS_ERRORTYPESENTRY']._serialized_options = b'8\001'
|
|
38
|
+
_globals['_ENGINEMETRIC_LABELSENTRY']._loaded_options = None
|
|
39
|
+
_globals['_ENGINEMETRIC_LABELSENTRY']._serialized_options = b'8\001'
|
|
40
|
+
_globals['_OUTCOME']._serialized_start=4511
|
|
41
|
+
_globals['_OUTCOME']._serialized_end=4633
|
|
42
|
+
_globals['_ACTIVITYATTEMPT']._serialized_start=115
|
|
43
|
+
_globals['_ACTIVITYATTEMPT']._serialized_end=946
|
|
44
|
+
_globals['_ACTIVITYSTATS']._serialized_start=949
|
|
45
|
+
_globals['_ACTIVITYSTATS']._serialized_end=1739
|
|
46
|
+
_globals['_ACTIVITYSTATS_ERRORTYPESENTRY']._serialized_start=1678
|
|
47
|
+
_globals['_ACTIVITYSTATS_ERRORTYPESENTRY']._serialized_end=1739
|
|
48
|
+
_globals['_INGESTACTIVITYEVENTSREQUEST']._serialized_start=1742
|
|
49
|
+
_globals['_INGESTACTIVITYEVENTSREQUEST']._serialized_end=2007
|
|
50
|
+
_globals['_WORKERBUFFERREPORT']._serialized_start=2010
|
|
51
|
+
_globals['_WORKERBUFFERREPORT']._serialized_end=2170
|
|
52
|
+
_globals['_INGESTACTIVITYEVENTSRESPONSE']._serialized_start=2172
|
|
53
|
+
_globals['_INGESTACTIVITYEVENTSRESPONSE']._serialized_end=2230
|
|
54
|
+
_globals['_WORKFLOWRUN']._serialized_start=2233
|
|
55
|
+
_globals['_WORKFLOWRUN']._serialized_end=2940
|
|
56
|
+
_globals['_LISTRUNSREQUEST']._serialized_start=2943
|
|
57
|
+
_globals['_LISTRUNSREQUEST']._serialized_end=3135
|
|
58
|
+
_globals['_LISTRUNSRESPONSE']._serialized_start=3138
|
|
59
|
+
_globals['_LISTRUNSRESPONSE']._serialized_end=3276
|
|
60
|
+
_globals['_ENGINEMETRIC']._serialized_start=3279
|
|
61
|
+
_globals['_ENGINEMETRIC']._serialized_end=3598
|
|
62
|
+
_globals['_ENGINEMETRIC_LABELSENTRY']._serialized_start=3541
|
|
63
|
+
_globals['_ENGINEMETRIC_LABELSENTRY']._serialized_end=3598
|
|
64
|
+
_globals['_ENGINEMETRICSREQUEST']._serialized_start=3601
|
|
65
|
+
_globals['_ENGINEMETRICSREQUEST']._serialized_end=3735
|
|
66
|
+
_globals['_ENGINEMETRICSRESPONSE']._serialized_start=3737
|
|
67
|
+
_globals['_ENGINEMETRICSRESPONSE']._serialized_end=3864
|
|
68
|
+
_globals['_UPDATEREJECTIONSREQUEST']._serialized_start=3866
|
|
69
|
+
_globals['_UPDATEREJECTIONSREQUEST']._serialized_end=3926
|
|
70
|
+
_globals['_UPDATEREJECTIONSRESPONSE']._serialized_start=3929
|
|
71
|
+
_globals['_UPDATEREJECTIONSRESPONSE']._serialized_end=4081
|
|
72
|
+
_globals['_ACTIVITYSTATSREQUEST']._serialized_start=4084
|
|
73
|
+
_globals['_ACTIVITYSTATSREQUEST']._serialized_end=4383
|
|
74
|
+
_globals['_ACTIVITYSTATSRESPONSE']._serialized_start=4385
|
|
75
|
+
_globals['_ACTIVITYSTATSRESPONSE']._serialized_end=4509
|
|
76
|
+
# @@protoc_insertion_point(module_scope)
|