vortexpy 4.3.13__tar.gz → 4.3.14__tar.gz
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.
- {vortexpy-4.3.13 → vortexpy-4.3.14}/PKG-INFO +1 -1
- {vortexpy-4.3.13 → vortexpy-4.3.14}/pyproject.toml +1 -1
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/__init__.py +1 -1
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/twisted_runtime_metrics.py +105 -60
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/twisted_runtime_metrics_test.py +34 -9
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/PKG-INFO +1 -1
- {vortexpy-4.3.13 → vortexpy-4.3.14}/README.md +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/TwistedDeferredTimeout.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_http_upgraded_websocket_ping_client.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_http_upgraded_websocket_ping_server.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_http_upgraded_websocket_rpc_test_client.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_http_upgraded_websocket_rpc_test_server.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_websocket_rpc_test_client.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/run_websocket_rpc_test_server.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/setup_example_logging.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/example/store_and_load_json.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/setup.cfg +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/DataWrapTuple.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/DeferUtil.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/DeferUtil_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/Jsonable.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/MtlsAuthorizedClientRegistry.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/MtlsAuthorizedClientRegistry_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/MtlsServerSslOptions.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/Payload.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadEndpoint.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadEndpointTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadEnvelope.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadFilterKeys.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadIO.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadPriority.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadResponse.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadResponseTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadResponse_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PayloadTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/PerformTestActionTuple.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/SerialiseUtil.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/SerialiseUtil_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TestTuple.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/Tuple.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleAction.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleBson.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleBson_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleDataForTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleDocumentConverter.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TuplePerfTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TuplePolymorphicTupleTypeFieldArgTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleRestful.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleRestful_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleSelector.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/TupleTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexAccessControlContextABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexAuthenticatorABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexClientHttp.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexClientHttpTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexClientTcp.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexClientWebsocketFactory.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexConnectionABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexEndpointPermission.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexFactory.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexFactory_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexPayloadProtocol.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexPermission.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexPermissionError.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServer.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerConnection.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerConnection_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerHttpResource.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerTcp.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerWebsocket.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServerWebsocket_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexServer_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexSession.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexSession_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexTcpMemoryLeakPayloadTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexTcpMemoryLeakRawTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexUtil.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexUtil_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexWritePushProducer.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/VortexWritePushProducer_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/TupleDataLiveLockManager.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/TupleDataLoader.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/TupleDataLoaderDelegate.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/TupleDataLoaderTupleABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/TupleDataLoaderTuples.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/data_loader/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/event_bus/TupleChangeEventABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/event_bus/TupleChangeEventBus.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/event_bus/TupleChangeEventBusObserverABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/event_bus/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionProcessor.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionProcessorProxy.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionProcessorTestHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionProcessor_shutdown_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionPushOffline.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleActionPushOffline_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataAccessGranterABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataActionClient.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableCache.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableCache_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableHandler_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableProxyHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableProxyHandler_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObservableTestHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataObserverClient.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/TupleDataProviderABC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/VortexJSTupleLoaderTestHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/handler/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/mypy_plugin.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/payload_many_tuples_benchmark_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/py.typed +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/GzippedDataHttpClient.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/GzippedDataHttpClientTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/GzippedPayloadHttpClient.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/RestfulHttpClient.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/RestfulResource.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/restful_http_client_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/restful/restful_resource_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/rpc/RPC.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/rpc/RPCTest.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/rpc/RPC_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/rpc/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/sqla_orm/OrmCrudHandler.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/sqla_orm/TupleProviderForDb.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/sqla_orm/VortexTupleJson.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/sqla_orm/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/storage/TupleActionStorageSqlite.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/storage/TupleStorageSqlite.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/storage/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/__init__.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/constants.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/json_schema_node_tuple.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/tuple_json_schema_builder.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/tuple_json_schema_test.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/tuple_json_schema_test_tuples.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_test_fixtures.py +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/SOURCES.txt +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/dependency_links.txt +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/entry_points.txt +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/requires.txt +0 -0
- {vortexpy-4.3.13 → vortexpy-4.3.14}/vortexpy.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vortexpy"
|
|
7
|
-
version = "4.3.
|
|
7
|
+
version = "4.3.14"
|
|
8
8
|
license = {text = "MIT"}
|
|
9
9
|
authors = [{name = "Flying Ion Pty Ltd", email = "contact@flyingion.com"}]
|
|
10
10
|
description = "Flying Ion's observable, routable, data serialisation and transport code."
|
|
@@ -146,13 +146,20 @@ class TwistedRuntimeMetrics:
|
|
|
146
146
|
def snapshotAndResetWindow(cls) -> TwistedRuntimeMetricsSnapshot:
|
|
147
147
|
return cls._collector()._snapshotAndResetWindow()
|
|
148
148
|
|
|
149
|
+
@classmethod
|
|
150
|
+
def snapshotWindow(cls) -> TwistedRuntimeMetricsSnapshot:
|
|
151
|
+
"""Snapshot the current window counters without resetting them."""
|
|
152
|
+
return cls._collector()._snapshotWindow()
|
|
153
|
+
|
|
149
154
|
def _start(self, reactorArg: Any) -> None:
|
|
150
155
|
if self._started:
|
|
151
156
|
return
|
|
152
157
|
from twisted.internet.task import LoopingCall
|
|
153
158
|
|
|
154
159
|
self._windowStartedMonotonic = time.monotonic()
|
|
155
|
-
self._nextExpectedMonotonic =
|
|
160
|
+
self._nextExpectedMonotonic = (
|
|
161
|
+
time.monotonic() + REACTOR_LAG_TICK_SECONDS
|
|
162
|
+
)
|
|
156
163
|
self._loop = LoopingCall(
|
|
157
164
|
vortexLoopingCallCatchWithMetrics(logger)(self._tickReactorLag)
|
|
158
165
|
)
|
|
@@ -185,9 +192,12 @@ class TwistedRuntimeMetrics:
|
|
|
185
192
|
with self._metricsLock:
|
|
186
193
|
self._loopingCallExceptionCount += 1
|
|
187
194
|
methodCount = (
|
|
188
|
-
self._loopingCallExceptionCountByMethod.get(methodQualname, 0)
|
|
195
|
+
self._loopingCallExceptionCountByMethod.get(methodQualname, 0)
|
|
196
|
+
+ 1
|
|
197
|
+
)
|
|
198
|
+
self._loopingCallExceptionCountByMethod[methodQualname] = (
|
|
199
|
+
methodCount
|
|
189
200
|
)
|
|
190
|
-
self._loopingCallExceptionCountByMethod[methodQualname] = methodCount
|
|
191
201
|
self._loopingCallLastExceptionMethod = methodQualname
|
|
192
202
|
self._loopingCallLastExceptionFrame = exceptionFrame
|
|
193
203
|
longestCount = 0
|
|
@@ -276,6 +286,20 @@ class TwistedRuntimeMetrics:
|
|
|
276
286
|
limitConcurrencyMostQueuedCount,
|
|
277
287
|
)
|
|
278
288
|
|
|
289
|
+
def _snapshotWindow(self) -> TwistedRuntimeMetricsSnapshot:
|
|
290
|
+
from twisted.internet import reactor
|
|
291
|
+
|
|
292
|
+
pool = reactor.getThreadPool() # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue]
|
|
293
|
+
threadPoolBusy = len(pool.working)
|
|
294
|
+
threadPoolQueued = len(pool.waiters)
|
|
295
|
+
|
|
296
|
+
with self._metricsLock:
|
|
297
|
+
return self._utilBuildSnapshotLocked(
|
|
298
|
+
pool,
|
|
299
|
+
threadPoolBusy,
|
|
300
|
+
threadPoolQueued,
|
|
301
|
+
)
|
|
302
|
+
|
|
279
303
|
def _snapshotAndResetWindow(self) -> TwistedRuntimeMetricsSnapshot:
|
|
280
304
|
from twisted.internet import reactor
|
|
281
305
|
|
|
@@ -284,64 +308,79 @@ class TwistedRuntimeMetrics:
|
|
|
284
308
|
threadPoolQueued = len(pool.waiters)
|
|
285
309
|
|
|
286
310
|
with self._metricsLock:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
limitConcurrencyQueued,
|
|
292
|
-
limitConcurrencyMax,
|
|
293
|
-
limitConcurrencyLimiterCount,
|
|
294
|
-
limitConcurrencySaturatedCount,
|
|
295
|
-
limitConcurrencyMostQueuedMethod,
|
|
296
|
-
limitConcurrencyMostQueuedCount,
|
|
297
|
-
) = self._snapshotLimitConcurrencyStateLocked()
|
|
298
|
-
snapshot = TwistedRuntimeMetricsSnapshot(
|
|
299
|
-
threadPoolBusy=threadPoolBusy,
|
|
300
|
-
threadPoolQueued=threadPoolQueued,
|
|
301
|
-
threadPoolMax=pool.max,
|
|
302
|
-
threadedCallCount=self._threadedCallCount,
|
|
303
|
-
longestThreadedMethodName=self._longestThreadedMethodName,
|
|
304
|
-
longestThreadedMethodMs=self._longestThreadedMethodMs,
|
|
305
|
-
longestThreadedMethodFrame=self._longestThreadedMethodFrame,
|
|
306
|
-
longestReactorBlockMs=self._longestReactorBlockMs,
|
|
307
|
-
longestReactorBlockFrame=self._longestReactorBlockFrame,
|
|
308
|
-
loopingCallExceptionCount=self._loopingCallExceptionCount,
|
|
309
|
-
loopingCallLongestExceptionMethod=(
|
|
310
|
-
self._loopingCallLongestExceptionMethod
|
|
311
|
-
),
|
|
312
|
-
loopingCallLastExceptionMethod=(self._loopingCallLastExceptionMethod),
|
|
313
|
-
loopingCallLastExceptionFrame=(self._loopingCallLastExceptionFrame),
|
|
314
|
-
limitConcurrencyRunning=limitConcurrencyRunning,
|
|
315
|
-
limitConcurrencyQueued=limitConcurrencyQueued,
|
|
316
|
-
limitConcurrencyMax=limitConcurrencyMax,
|
|
317
|
-
limitConcurrencyLimiterCount=limitConcurrencyLimiterCount,
|
|
318
|
-
limitConcurrencySaturatedCount=limitConcurrencySaturatedCount,
|
|
319
|
-
limitConcurrencyCallCount=self._limitConcurrencyCallCount,
|
|
320
|
-
limitConcurrencyCallTimeoutCount=(
|
|
321
|
-
self._limitConcurrencyCallTimeoutCount
|
|
322
|
-
),
|
|
323
|
-
limitConcurrencyLastCallTimeoutMethodName=(
|
|
324
|
-
self._limitConcurrencyLastCallTimeoutMethodName
|
|
325
|
-
),
|
|
326
|
-
longestLimitConcurrencyMethodName=(
|
|
327
|
-
self._longestLimitConcurrencyMethodName
|
|
328
|
-
),
|
|
329
|
-
longestLimitConcurrencyMethodMs=(
|
|
330
|
-
self._longestLimitConcurrencyMethodMs
|
|
331
|
-
),
|
|
332
|
-
longestLimitConcurrencyQueueWaitMs=(
|
|
333
|
-
self._longestLimitConcurrencyQueueWaitMs
|
|
334
|
-
),
|
|
335
|
-
longestLimitConcurrencyQueueWaitMethod=(
|
|
336
|
-
self._longestLimitConcurrencyQueueWaitMethod
|
|
337
|
-
),
|
|
338
|
-
limitConcurrencyMostQueuedMethod=limitConcurrencyMostQueuedMethod,
|
|
339
|
-
limitConcurrencyMostQueuedCount=limitConcurrencyMostQueuedCount,
|
|
340
|
-
windowSeconds=windowSeconds,
|
|
311
|
+
snapshot = self._utilBuildSnapshotLocked(
|
|
312
|
+
pool,
|
|
313
|
+
threadPoolBusy,
|
|
314
|
+
threadPoolQueued,
|
|
341
315
|
)
|
|
342
316
|
self._resetWindowCountersLocked()
|
|
343
317
|
return snapshot
|
|
344
318
|
|
|
319
|
+
def _utilBuildSnapshotLocked(
|
|
320
|
+
self,
|
|
321
|
+
pool: Any,
|
|
322
|
+
threadPoolBusy: int,
|
|
323
|
+
threadPoolQueued: int,
|
|
324
|
+
) -> TwistedRuntimeMetricsSnapshot:
|
|
325
|
+
"""Build one snapshot from current counters; caller holds the lock."""
|
|
326
|
+
elapsedSeconds = time.monotonic() - self._windowStartedMonotonic
|
|
327
|
+
windowSeconds = int(max(1, round(elapsedSeconds)))
|
|
328
|
+
(
|
|
329
|
+
limitConcurrencyRunning,
|
|
330
|
+
limitConcurrencyQueued,
|
|
331
|
+
limitConcurrencyMax,
|
|
332
|
+
limitConcurrencyLimiterCount,
|
|
333
|
+
limitConcurrencySaturatedCount,
|
|
334
|
+
limitConcurrencyMostQueuedMethod,
|
|
335
|
+
limitConcurrencyMostQueuedCount,
|
|
336
|
+
) = self._snapshotLimitConcurrencyStateLocked()
|
|
337
|
+
return TwistedRuntimeMetricsSnapshot(
|
|
338
|
+
threadPoolBusy=threadPoolBusy,
|
|
339
|
+
threadPoolQueued=threadPoolQueued,
|
|
340
|
+
threadPoolMax=pool.max,
|
|
341
|
+
threadedCallCount=self._threadedCallCount,
|
|
342
|
+
longestThreadedMethodName=self._longestThreadedMethodName,
|
|
343
|
+
longestThreadedMethodMs=self._longestThreadedMethodMs,
|
|
344
|
+
longestThreadedMethodFrame=self._longestThreadedMethodFrame,
|
|
345
|
+
longestReactorBlockMs=self._longestReactorBlockMs,
|
|
346
|
+
longestReactorBlockFrame=self._longestReactorBlockFrame,
|
|
347
|
+
loopingCallExceptionCount=self._loopingCallExceptionCount,
|
|
348
|
+
loopingCallLongestExceptionMethod=(
|
|
349
|
+
self._loopingCallLongestExceptionMethod
|
|
350
|
+
),
|
|
351
|
+
loopingCallLastExceptionMethod=(
|
|
352
|
+
self._loopingCallLastExceptionMethod
|
|
353
|
+
),
|
|
354
|
+
loopingCallLastExceptionFrame=(self._loopingCallLastExceptionFrame),
|
|
355
|
+
limitConcurrencyRunning=limitConcurrencyRunning,
|
|
356
|
+
limitConcurrencyQueued=limitConcurrencyQueued,
|
|
357
|
+
limitConcurrencyMax=limitConcurrencyMax,
|
|
358
|
+
limitConcurrencyLimiterCount=limitConcurrencyLimiterCount,
|
|
359
|
+
limitConcurrencySaturatedCount=limitConcurrencySaturatedCount,
|
|
360
|
+
limitConcurrencyCallCount=self._limitConcurrencyCallCount,
|
|
361
|
+
limitConcurrencyCallTimeoutCount=(
|
|
362
|
+
self._limitConcurrencyCallTimeoutCount
|
|
363
|
+
),
|
|
364
|
+
limitConcurrencyLastCallTimeoutMethodName=(
|
|
365
|
+
self._limitConcurrencyLastCallTimeoutMethodName
|
|
366
|
+
),
|
|
367
|
+
longestLimitConcurrencyMethodName=(
|
|
368
|
+
self._longestLimitConcurrencyMethodName
|
|
369
|
+
),
|
|
370
|
+
longestLimitConcurrencyMethodMs=(
|
|
371
|
+
self._longestLimitConcurrencyMethodMs
|
|
372
|
+
),
|
|
373
|
+
longestLimitConcurrencyQueueWaitMs=(
|
|
374
|
+
self._longestLimitConcurrencyQueueWaitMs
|
|
375
|
+
),
|
|
376
|
+
longestLimitConcurrencyQueueWaitMethod=(
|
|
377
|
+
self._longestLimitConcurrencyQueueWaitMethod
|
|
378
|
+
),
|
|
379
|
+
limitConcurrencyMostQueuedMethod=limitConcurrencyMostQueuedMethod,
|
|
380
|
+
limitConcurrencyMostQueuedCount=limitConcurrencyMostQueuedCount,
|
|
381
|
+
windowSeconds=windowSeconds,
|
|
382
|
+
)
|
|
383
|
+
|
|
345
384
|
def _tickReactorLag(self) -> None:
|
|
346
385
|
now = time.monotonic()
|
|
347
386
|
lagMs = (now - self._nextExpectedMonotonic) * 1000.0
|
|
@@ -394,7 +433,9 @@ class TwistedRuntimeMetrics:
|
|
|
394
433
|
if frame is None:
|
|
395
434
|
return None
|
|
396
435
|
for summary in reversed(traceback.extract_stack(frame)):
|
|
397
|
-
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
436
|
+
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
437
|
+
summary.filename
|
|
438
|
+
):
|
|
398
439
|
continue
|
|
399
440
|
return f"{summary.filename}:{summary.name}:{summary.lineno}"
|
|
400
441
|
return None
|
|
@@ -402,7 +443,9 @@ class TwistedRuntimeMetrics:
|
|
|
402
443
|
@staticmethod
|
|
403
444
|
def _captureWorkerThreadFrame() -> str | None:
|
|
404
445
|
for summary in reversed(traceback.extract_stack()):
|
|
405
|
-
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
446
|
+
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
447
|
+
summary.filename
|
|
448
|
+
):
|
|
406
449
|
continue
|
|
407
450
|
return f"{summary.filename}:{summary.name}:{summary.lineno}"
|
|
408
451
|
return None
|
|
@@ -413,7 +456,9 @@ class TwistedRuntimeMetrics:
|
|
|
413
456
|
if excTraceback is None:
|
|
414
457
|
return None
|
|
415
458
|
for summary in reversed(traceback.extract_tb(excTraceback)):
|
|
416
|
-
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
459
|
+
if TwistedRuntimeMetrics._utilSkipInternalMetricsFrame(
|
|
460
|
+
summary.filename
|
|
461
|
+
):
|
|
417
462
|
continue
|
|
418
463
|
return f"{summary.filename}:{summary.name}:{summary.lineno}"
|
|
419
464
|
return None
|
|
@@ -10,11 +10,11 @@ from typing import Any
|
|
|
10
10
|
import pytest
|
|
11
11
|
from twisted.internet.defer import Deferred, fail, succeed
|
|
12
12
|
|
|
13
|
-
from vortex.VortexUtil import limitConcurrency
|
|
14
13
|
from vortex.twisted_runtime_metrics import (
|
|
15
14
|
TwistedRuntimeMetrics,
|
|
16
15
|
vortexLoopingCallCatchWithMetrics,
|
|
17
16
|
)
|
|
17
|
+
from vortex.VortexUtil import limitConcurrency
|
|
18
18
|
|
|
19
19
|
logger = logging.getLogger(__name__)
|
|
20
20
|
|
|
@@ -46,7 +46,9 @@ def testRecordThreadedCallTracksCountAndLongestMethod() -> None:
|
|
|
46
46
|
collector._recordThreadedCall("slow.Method", 100.0)
|
|
47
47
|
collector._recordThreadedCall("slower.Method", 250.5, "slow.py:run:10")
|
|
48
48
|
snapshot = TwistedRuntimeMetrics.snapshotAndResetWindow()
|
|
49
|
-
assert snapshot.threadedCallCount == 2,
|
|
49
|
+
assert snapshot.threadedCallCount == 2, (
|
|
50
|
+
"both threaded calls must count in window"
|
|
51
|
+
)
|
|
50
52
|
assert snapshot.longestThreadedMethodName == "slower.Method", (
|
|
51
53
|
"longest name must be the slowest call"
|
|
52
54
|
)
|
|
@@ -56,18 +58,39 @@ def testRecordThreadedCallTracksCountAndLongestMethod() -> None:
|
|
|
56
58
|
assert snapshot.longestThreadedMethodFrame == "slow.py:run:10", (
|
|
57
59
|
"slow-call frame must be preserved"
|
|
58
60
|
)
|
|
59
|
-
assert snapshot.windowSeconds >= 1,
|
|
61
|
+
assert snapshot.windowSeconds >= 1, (
|
|
62
|
+
"snapshot must report elapsed window seconds"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def testSnapshotWindowDoesNotResetCounters() -> None:
|
|
67
|
+
TwistedRuntimeMetrics._collector()._recordThreadedCall("one.Method", 50.0)
|
|
68
|
+
firstSnapshot = TwistedRuntimeMetrics.snapshotWindow()
|
|
69
|
+
secondSnapshot = TwistedRuntimeMetrics.snapshotWindow()
|
|
70
|
+
assert firstSnapshot.threadedCallCount == 1, (
|
|
71
|
+
"first snapshot includes recorded call"
|
|
72
|
+
)
|
|
73
|
+
assert secondSnapshot.threadedCallCount == 1, (
|
|
74
|
+
"read-only snapshot must leave window counters intact"
|
|
75
|
+
)
|
|
76
|
+
assert secondSnapshot.longestThreadedMethodMs == 50.0, (
|
|
77
|
+
"read-only snapshot must preserve longest threaded method"
|
|
78
|
+
)
|
|
60
79
|
|
|
61
80
|
|
|
62
81
|
def testSnapshotResetsWindowCounters() -> None:
|
|
63
82
|
TwistedRuntimeMetrics._collector()._recordThreadedCall("one.Method", 50.0)
|
|
64
83
|
firstSnapshot = TwistedRuntimeMetrics.snapshotAndResetWindow()
|
|
65
84
|
secondSnapshot = TwistedRuntimeMetrics.snapshotAndResetWindow()
|
|
66
|
-
assert firstSnapshot.threadedCallCount == 1,
|
|
85
|
+
assert firstSnapshot.threadedCallCount == 1, (
|
|
86
|
+
"first snapshot includes recorded call"
|
|
87
|
+
)
|
|
67
88
|
assert firstSnapshot.longestThreadedMethodMs == 50.0, (
|
|
68
89
|
"first snapshot longest ms must match recorded call"
|
|
69
90
|
)
|
|
70
|
-
assert secondSnapshot.threadedCallCount == 0,
|
|
91
|
+
assert secondSnapshot.threadedCallCount == 0, (
|
|
92
|
+
"window counters reset after snapshot"
|
|
93
|
+
)
|
|
71
94
|
assert secondSnapshot.longestThreadedMethodMs == 0.0, (
|
|
72
95
|
"longest ms resets to zero after snapshot"
|
|
73
96
|
)
|
|
@@ -96,7 +119,9 @@ def testLoopingCallLongestExceptionMethodUsesHighestCount() -> None:
|
|
|
96
119
|
collector._recordLoopingCallException("noisyTick", "a.py:2")
|
|
97
120
|
collector._recordLoopingCallException("quietTick", "b.py:1")
|
|
98
121
|
snapshot = TwistedRuntimeMetrics.snapshotAndResetWindow()
|
|
99
|
-
assert snapshot.loopingCallExceptionCount == 3,
|
|
122
|
+
assert snapshot.loopingCallExceptionCount == 3, (
|
|
123
|
+
"three exceptions must be counted"
|
|
124
|
+
)
|
|
100
125
|
assert snapshot.loopingCallLongestExceptionMethod == "noisyTick", (
|
|
101
126
|
"longest method is highest per-method exception count"
|
|
102
127
|
)
|
|
@@ -191,9 +216,9 @@ def testLoopingCallCatchWithMetricsRecordsDeferredFailure() -> None:
|
|
|
191
216
|
assert snapshot.loopingCallExceptionCount == 1, (
|
|
192
217
|
"deferred tick failure must increment exception count"
|
|
193
218
|
)
|
|
194
|
-
assert
|
|
195
|
-
|
|
196
|
-
)
|
|
219
|
+
assert (
|
|
220
|
+
snapshot.loopingCallLongestExceptionMethod == "failingDeferredTick"
|
|
221
|
+
), "deferred failure must set longest exception method"
|
|
197
222
|
assert snapshot.loopingCallLastExceptionMethod == "failingDeferredTick", (
|
|
198
223
|
"deferred failure must set last exception method"
|
|
199
224
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vortexpy-4.3.13 → vortexpy-4.3.14}/vortex/tuple_json_schema/tuple_json_schema_test_tuples.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|