airbyte-internal-ops 0.10.0__py3-none-any.whl → 0.10.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airbyte-internal-ops
3
- Version: 0.10.0
3
+ Version: 0.10.2
4
4
  Summary: MCP and API interfaces that let the agents do the admin work
5
5
  Author-email: Aaron Steers <aj@airbyte.io>
6
6
  Keywords: admin,airbyte,api,mcp
@@ -231,7 +231,7 @@ airbyte_ops_mcp/cli/gh.py,sha256=koJPu0MDB6AW7mJq2z4dZV65ofvsZTkqoeitGF8KJR8,536
231
231
  airbyte_ops_mcp/cli/local.py,sha256=amxtJ7aY1nrOs36zuWkV7jZVMyHNLT7HDUvyyOXF8mM,44459
232
232
  airbyte_ops_mcp/cli/registry.py,sha256=CVm15_6YWpLD99DZ8f8y68npXJw01Ckde7Ty3o89YNE,16631
233
233
  airbyte_ops_mcp/cloud_admin/__init__.py,sha256=cqE96Q10Kp6elhH9DAi6TVsIwSUy3sooDLLrxTaktGk,816
234
- airbyte_ops_mcp/cloud_admin/api_client.py,sha256=2DNYx-GXOTCuP9-rEkZFTM8MIR3MDnXSaqs_z1DsTwQ,70361
234
+ airbyte_ops_mcp/cloud_admin/api_client.py,sha256=tqqXZumM5UGZ81RkA3ZAkIYp2z6e8izSnic9KBTnnSo,72851
235
235
  airbyte_ops_mcp/cloud_admin/auth.py,sha256=qE2Aqe0qbZB755KscL65s54Jz78-F-X5a8fXKsrYEOQ,3749
236
236
  airbyte_ops_mcp/cloud_admin/connection_config.py,sha256=9opGQer-cGMJANmm-LFLMwvMCNu3nzxa2n2XHkZj9Fw,4899
237
237
  airbyte_ops_mcp/cloud_admin/models.py,sha256=Wn6O48Yp2QB3jsknmw-mG-LJ6GdBIyAg06MGLC1kOjM,8299
@@ -269,13 +269,13 @@ airbyte_ops_mcp/mcp/_guidance.py,sha256=n0dLggQXNi2PKZ0eFDqQx5YIjhQpMnI3xcjouub9
269
269
  airbyte_ops_mcp/mcp/cloud_connector_versions.py,sha256=dRKrgsRGadQieTSvBrc5HYI6TTDzVAT6-4tiOHNcDHU,36244
270
270
  airbyte_ops_mcp/mcp/connector_analysis.py,sha256=OC4KrOSkMkKPkOisWnSv96BDDE5TQYHq-Jxa2vtjJpo,298
271
271
  airbyte_ops_mcp/mcp/connector_qa.py,sha256=aImpqdnqBPDrz10BS0owsV4kuIU2XdalzgbaGZsbOL0,258
272
- airbyte_ops_mcp/mcp/connector_rollout.py,sha256=KYQhRCcpJCquhX_aGNjhT9WKT5lqDpNKNA1Wki-7zPU,29020
272
+ airbyte_ops_mcp/mcp/connector_rollout.py,sha256=HxHAXZm3bIf_DjNJ04954twTyQHw-X9BEYJJFE6xCPg,32635
273
273
  airbyte_ops_mcp/mcp/gcp_logs.py,sha256=QCDQHmsxQHJ26BB0sxkBgKXr7Ja9wVFkdpY6423H-xo,2677
274
274
  airbyte_ops_mcp/mcp/github_actions.py,sha256=G0NmjNVWpVtLXdQnhX7qJwPFkfEX5gBXf55xt0FpJJ0,11752
275
275
  airbyte_ops_mcp/mcp/github_repo_ops.py,sha256=YHeuN7Xc_L3xkJ-F3l1t1TIPW2j2CjecBDbb0DUvZO8,5306
276
276
  airbyte_ops_mcp/mcp/metadata.py,sha256=fwGW97WknR5lfKcQnFtK6dU87aA6TmLj1NkKyqDAV9g,270
277
277
  airbyte_ops_mcp/mcp/prerelease.py,sha256=jSrAwk95vZLfwYFn5Menb-ziAMTUZnzAMHIJAitd9x8,9553
278
- airbyte_ops_mcp/mcp/prod_db_queries.py,sha256=iesP8H2hCmkdjsmLgYOrwqNQeQwbcScQc4tr4cfs8es,56334
278
+ airbyte_ops_mcp/mcp/prod_db_queries.py,sha256=GzR_R4QXy15benTmF6sKdwP0YBx18GOvB-zGqz8AOeY,53228
279
279
  airbyte_ops_mcp/mcp/prompts.py,sha256=v4bguskw7hSsISkseACzKQm5QwrIXmiwbs27oclXTE8,1591
280
280
  airbyte_ops_mcp/mcp/registry.py,sha256=PW-VYUj42qx2pQ_apUkVaoUFq7VgB9zEU7-aGrkSCCw,290
281
281
  airbyte_ops_mcp/mcp/regression_tests.py,sha256=zwdQ-ymUhWtVcIjwiNIZAC151GKhuxi55HDi4S91RnI,17046
@@ -283,8 +283,8 @@ airbyte_ops_mcp/mcp/server.py,sha256=7VO-awh4gh51EiYCkUvEyQd4r1gl6XRJ4-I-JybkEiA
283
283
  airbyte_ops_mcp/prod_db_access/__init__.py,sha256=5pxouMPY1beyWlB0UwPnbaLTKTHqU6X82rbbgKY2vYU,1069
284
284
  airbyte_ops_mcp/prod_db_access/db_engine.py,sha256=VUqEWZtharJUR-Cri_pMwtGh1C4Neu4s195mbEXlm-w,9190
285
285
  airbyte_ops_mcp/prod_db_access/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
286
- airbyte_ops_mcp/prod_db_access/queries.py,sha256=OMnIejwVoQSaTV1It1btzui6Zmrvihh3d6KNZgyyE7I,27741
287
- airbyte_ops_mcp/prod_db_access/sql.py,sha256=J89eGlrG_0NPtpAuVVKTBS9tG3LKGj0DK-zTGUEzvFA,49526
286
+ airbyte_ops_mcp/prod_db_access/queries.py,sha256=AkI6sclY2KNrolzXeDyh2s2aYFdUbaoTkLYxQpupasw,25577
287
+ airbyte_ops_mcp/prod_db_access/sql.py,sha256=6t4_ePFgEIGrZzoj9IRdeBydw7im1XxTS9bfsaZ290c,45888
288
288
  airbyte_ops_mcp/registry/__init__.py,sha256=iEaPlt9GrnlaLbc__98TguNeZG8wuQu7S-_2QkhHcbA,858
289
289
  airbyte_ops_mcp/registry/_gcs_util.py,sha256=3dL7iqpyoSPfl2nGBPp73TqrqGWI4Ks6egKpQXDnw24,2838
290
290
  airbyte_ops_mcp/registry/connector_stubs.py,sha256=pBzaQIOgCfBvHuy3_N45amU9Do2ALDpU8q5HnZySPTQ,5807
@@ -310,7 +310,7 @@ airbyte_ops_mcp/regression_tests/regression/comparators.py,sha256=MJkLZEKHivgrG0
310
310
  airbyte_ops_mcp/regression_tests/validation/__init__.py,sha256=MBEwGOoNuqT4_oCahtoK62OKWIjUCfWa7vZTxNj_0Ek,1532
311
311
  airbyte_ops_mcp/regression_tests/validation/catalog_validators.py,sha256=jqqVAMOk0mtdPgwu4d0hA0ZEjtsNh5gapvGydRv3_qk,12553
312
312
  airbyte_ops_mcp/regression_tests/validation/record_validators.py,sha256=RjauAhKWNwxMBTu0eNS2hMFNQVs5CLbQU51kp6FOVDk,7432
313
- airbyte_internal_ops-0.10.0.dist-info/METADATA,sha256=eP4lUCpuijAH7aJIkDW4n3mZOIoMqq8nvkF3IU5EqyM,6002
314
- airbyte_internal_ops-0.10.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
315
- airbyte_internal_ops-0.10.0.dist-info/entry_points.txt,sha256=WxP0l7bRFss4Cr5uQqVj9mTEKwnRKouNuphXQF0lotA,171
316
- airbyte_internal_ops-0.10.0.dist-info/RECORD,,
313
+ airbyte_internal_ops-0.10.2.dist-info/METADATA,sha256=R_eF8wt1HmZ88Ct0dLSqGnEV-N1y9BI2oUscodQO5wg,6002
314
+ airbyte_internal_ops-0.10.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
315
+ airbyte_internal_ops-0.10.2.dist-info/entry_points.txt,sha256=WxP0l7bRFss4Cr5uQqVj9mTEKwnRKouNuphXQF0lotA,171
316
+ airbyte_internal_ops-0.10.2.dist-info/RECORD,,
@@ -1768,3 +1768,73 @@ def finalize_connector_rollout(
1768
1768
  )
1769
1769
 
1770
1770
  return response.json()
1771
+
1772
+
1773
+ def get_actor_sync_info(
1774
+ rollout_id: str,
1775
+ config_api_root: str,
1776
+ client_id: str | None = None,
1777
+ client_secret: str | None = None,
1778
+ bearer_token: str | None = None,
1779
+ ) -> dict[str, Any]:
1780
+ """Get actor sync info for a connector rollout.
1781
+
1782
+ This function calls the platform API to get sync statistics for actors
1783
+ participating in a rollout. Unlike the SQL-based approach, this endpoint
1784
+ filters sync stats to only include syncs that actually used the RC version
1785
+ associated with the rollout.
1786
+
1787
+ Args:
1788
+ rollout_id: The rollout ID (UUID)
1789
+ config_api_root: The Config API root URL (e.g., CLOUD_CONFIG_API_ROOT)
1790
+ client_id: The Airbyte Cloud client ID (required if no bearer_token)
1791
+ client_secret: The Airbyte Cloud client secret (required if no bearer_token)
1792
+ bearer_token: Pre-existing bearer token (takes precedence over client credentials)
1793
+
1794
+ Returns:
1795
+ Dictionary containing:
1796
+ - data.actorSelectionInfo: Info about actor selection (numActors, numPinnedToConnectorRollout, etc.)
1797
+ - data.syncs: Dict mapping actor_id to sync stats (numConnections, numSucceeded, numFailed)
1798
+
1799
+ Raises:
1800
+ PyAirbyteInputError: If the API request fails or rollout not found
1801
+ """
1802
+ access_token = _get_access_token(client_id, client_secret, bearer_token)
1803
+
1804
+ endpoint = f"{config_api_root}/connector_rollout/get_actor_sync_info"
1805
+ payload = {"id": rollout_id}
1806
+
1807
+ response = requests.post(
1808
+ endpoint,
1809
+ json=payload,
1810
+ headers={
1811
+ "Authorization": f"Bearer {access_token}",
1812
+ "User-Agent": ops_constants.USER_AGENT,
1813
+ "Content-Type": "application/json",
1814
+ },
1815
+ timeout=60,
1816
+ )
1817
+
1818
+ if response.status_code == 404:
1819
+ raise PyAirbyteInputError(
1820
+ message=f"Rollout not found: {rollout_id}",
1821
+ context={
1822
+ "rollout_id": rollout_id,
1823
+ "endpoint": endpoint,
1824
+ "status_code": response.status_code,
1825
+ "response": response.text,
1826
+ },
1827
+ )
1828
+
1829
+ if response.status_code != 200:
1830
+ raise PyAirbyteInputError(
1831
+ message=f"Failed to get actor sync info: {response.status_code} {response.text}",
1832
+ context={
1833
+ "rollout_id": rollout_id,
1834
+ "endpoint": endpoint,
1835
+ "status_code": response.status_code,
1836
+ "response": response.text,
1837
+ },
1838
+ )
1839
+
1840
+ return response.json()
@@ -17,7 +17,7 @@ from airbyte import constants
17
17
  from airbyte.exceptions import PyAirbyteInputError
18
18
  from fastmcp import Context, FastMCP
19
19
  from fastmcp_extensions import get_mcp_config, mcp_tool, register_mcp_tools
20
- from pydantic import Field
20
+ from pydantic import BaseModel, Field
21
21
 
22
22
  from airbyte_ops_mcp.cloud_admin import api_client
23
23
  from airbyte_ops_mcp.cloud_admin.auth import (
@@ -770,6 +770,109 @@ def finalize_connector_rollout(
770
770
  )
771
771
 
772
772
 
773
+ class RolloutActorSelectionInfo(BaseModel):
774
+ """Actor selection info for a connector rollout."""
775
+
776
+ num_actors: int = Field(description="Total actors using this connector")
777
+ num_pinned_to_connector_rollout: int = Field(
778
+ description="Actors specifically pinned to this rollout"
779
+ )
780
+ num_actors_eligible_or_already_pinned: int = Field(
781
+ description="Actors eligible for pinning or already pinned"
782
+ )
783
+
784
+
785
+ class RolloutActorSyncStats(BaseModel):
786
+ """Per-actor sync stats for a rollout (only syncs using the RC version)."""
787
+
788
+ actor_id: str = Field(description="Actor UUID")
789
+ num_connections: int = Field(description="Number of connections using this actor")
790
+ num_succeeded: int = Field(
791
+ description="Number of successful syncs using the RC version"
792
+ )
793
+ num_failed: int = Field(description="Number of failed syncs using the RC version")
794
+
795
+
796
+ class RolloutMonitoringResult(BaseModel):
797
+ """Complete monitoring result for a rollout from the platform API.
798
+
799
+ This uses the platform API's /get_actor_sync_info endpoint which filters
800
+ sync stats to only include syncs that actually used the RC version
801
+ associated with the rollout.
802
+ """
803
+
804
+ rollout_id: str = Field(description="Rollout UUID")
805
+ actor_selection_info: RolloutActorSelectionInfo = Field(
806
+ description="Actor selection info for the rollout"
807
+ )
808
+ actor_sync_stats: list[RolloutActorSyncStats] = Field(
809
+ description="Per-actor sync stats for actors pinned to the rollout"
810
+ )
811
+
812
+
813
+ @mcp_tool(
814
+ read_only=True,
815
+ idempotent=True,
816
+ )
817
+ def query_prod_rollout_monitoring_stats(
818
+ rollout_id: Annotated[
819
+ str,
820
+ Field(description="Rollout UUID to get monitoring stats for"),
821
+ ],
822
+ *,
823
+ ctx: Context,
824
+ ) -> RolloutMonitoringResult:
825
+ """Get monitoring stats for a connector rollout.
826
+
827
+ Returns actor selection info and per-actor sync stats for actors
828
+ participating in the rollout. This uses the platform API's
829
+ /get_actor_sync_info endpoint which filters sync stats to only include
830
+ syncs that actually used the RC version associated with the rollout.
831
+
832
+ This is more accurate than SQL-based approaches which count all syncs
833
+ regardless of which connector version was used.
834
+ """
835
+ auth = _resolve_cloud_auth(ctx)
836
+
837
+ response = api_client.get_actor_sync_info(
838
+ rollout_id=rollout_id,
839
+ config_api_root=constants.CLOUD_CONFIG_API_ROOT,
840
+ client_id=auth.client_id,
841
+ client_secret=auth.client_secret,
842
+ bearer_token=auth.bearer_token,
843
+ )
844
+
845
+ data = response.get("data", {})
846
+ actor_selection_info_data = data.get("actor_selection_info", {})
847
+ syncs_data = data.get("syncs", {})
848
+
849
+ actor_selection_info = RolloutActorSelectionInfo(
850
+ num_actors=actor_selection_info_data.get("num_actors", 0),
851
+ num_pinned_to_connector_rollout=actor_selection_info_data.get(
852
+ "num_pinned_to_connector_rollout", 0
853
+ ),
854
+ num_actors_eligible_or_already_pinned=actor_selection_info_data.get(
855
+ "num_actors_eligible_or_already_pinned", 0
856
+ ),
857
+ )
858
+
859
+ actor_sync_stats = [
860
+ RolloutActorSyncStats(
861
+ actor_id=actor_id,
862
+ num_connections=sync_info.get("num_connections", 0),
863
+ num_succeeded=sync_info.get("num_succeeded", 0),
864
+ num_failed=sync_info.get("num_failed", 0),
865
+ )
866
+ for actor_id, sync_info in syncs_data.items()
867
+ ]
868
+
869
+ return RolloutMonitoringResult(
870
+ rollout_id=rollout_id,
871
+ actor_selection_info=actor_selection_info,
872
+ actor_sync_stats=actor_sync_stats,
873
+ )
874
+
875
+
773
876
  def register_connector_rollout_tools(app: FastMCP) -> None:
774
877
  """Register connector rollout tools with the FastMCP app.
775
878
 
@@ -1412,93 +1412,6 @@ def query_prod_connector_rollouts(
1412
1412
  return [_row_to_connector_rollout_info(row) for row in rows]
1413
1413
 
1414
1414
 
1415
- class RolloutMonitoringStats(BaseModel):
1416
- """Aggregate monitoring stats for a connector rollout."""
1417
-
1418
- rollout_id: str = Field(description="Rollout UUID")
1419
- actor_definition_id: str = Field(description="Connector definition UUID")
1420
- num_actors: int = Field(description="Total actors using this connector")
1421
- num_actors_pinned: int = Field(
1422
- description="Actors with any version pin (eligible or already pinned)"
1423
- )
1424
- num_pinned_to_rollout: int = Field(
1425
- description="Actors specifically pinned to this rollout"
1426
- )
1427
-
1428
-
1429
- class RolloutActorSyncStats(BaseModel):
1430
- """Per-actor sync stats for a rollout."""
1431
-
1432
- actor_id: str = Field(description="Actor UUID")
1433
- num_succeeded: int = Field(description="Number of successful syncs")
1434
- num_failed: int = Field(description="Number of failed syncs")
1435
- num_connections: int = Field(description="Number of connections using this actor")
1436
-
1437
-
1438
- class RolloutMonitoringResult(BaseModel):
1439
- """Complete monitoring result for a rollout."""
1440
-
1441
- aggregate_stats: RolloutMonitoringStats = Field(
1442
- description="Aggregate counts for the rollout"
1443
- )
1444
- actor_stats: list[RolloutActorSyncStats] = Field(
1445
- description="Per-actor sync stats for actors pinned to the rollout"
1446
- )
1447
-
1448
-
1449
- @mcp_tool(
1450
- read_only=True,
1451
- idempotent=True,
1452
- )
1453
- def query_prod_rollout_monitoring_stats(
1454
- rollout_id: Annotated[
1455
- str,
1456
- Field(description="Rollout UUID to get monitoring stats for"),
1457
- ],
1458
- days_back: Annotated[
1459
- int,
1460
- Field(description="Number of days to look back for sync stats (default: 7)"),
1461
- ] = 7,
1462
- ) -> RolloutMonitoringResult:
1463
- """Get monitoring stats for a connector rollout.
1464
-
1465
- Returns aggregate counts (total actors, pinned actors, rollout-pinned actors)
1466
- and per-actor sync stats (succeeded, failed, connections) for actors
1467
- participating in the rollout. This replaces the Retool rollout monitoring UI.
1468
- """
1469
- from airbyte_ops_mcp.prod_db_access.queries import (
1470
- query_rollout_actor_sync_stats,
1471
- query_rollout_monitoring_stats,
1472
- )
1473
-
1474
- agg_stats = query_rollout_monitoring_stats(rollout_id=rollout_id)
1475
- if agg_stats is None:
1476
- raise ValueError(f"Rollout not found: {rollout_id}")
1477
-
1478
- actor_stats = query_rollout_actor_sync_stats(
1479
- rollout_id=rollout_id, days_back=days_back
1480
- )
1481
-
1482
- return RolloutMonitoringResult(
1483
- aggregate_stats=RolloutMonitoringStats(
1484
- rollout_id=str(agg_stats["rollout_id"]),
1485
- actor_definition_id=str(agg_stats["actor_definition_id"]),
1486
- num_actors=agg_stats["num_actors"] or 0,
1487
- num_actors_pinned=agg_stats["num_actors_pinned"] or 0,
1488
- num_pinned_to_rollout=agg_stats["num_pinned_to_rollout"] or 0,
1489
- ),
1490
- actor_stats=[
1491
- RolloutActorSyncStats(
1492
- actor_id=str(row["actor_id"]),
1493
- num_succeeded=row["num_succeeded"] or 0,
1494
- num_failed=row["num_failed"] or 0,
1495
- num_connections=row["num_connections"] or 0,
1496
- )
1497
- for row in actor_stats
1498
- ],
1499
- )
1500
-
1501
-
1502
1415
  def register_prod_db_query_tools(app: FastMCP) -> None:
1503
1416
  """Register prod DB query tools with the FastMCP app."""
1504
1417
  register_mcp_tools(app, mcp_module=__name__)
@@ -42,8 +42,6 @@ from airbyte_ops_mcp.prod_db_access.sql import (
42
42
  SELECT_RECENT_SUCCESSFUL_SYNCS_FOR_SOURCE_CONNECTOR,
43
43
  SELECT_RECENT_SYNCS_FOR_DESTINATION_CONNECTOR,
44
44
  SELECT_RECENT_SYNCS_FOR_SOURCE_CONNECTOR,
45
- SELECT_ROLLOUT_ACTOR_SYNC_STATS,
46
- SELECT_ROLLOUT_AGGREGATE_STATS,
47
45
  SELECT_SOURCE_CONNECTION_STATS,
48
46
  SELECT_SUCCESSFUL_SYNCS_FOR_VERSION,
49
47
  SELECT_SYNC_RESULTS_FOR_VERSION,
@@ -701,62 +699,3 @@ def query_connector_rollouts(
701
699
  query_name="SELECT_ACTIVE_CONNECTOR_ROLLOUTS",
702
700
  gsm_client=gsm_client,
703
701
  )
704
-
705
-
706
- def query_rollout_monitoring_stats(
707
- rollout_id: str,
708
- *,
709
- gsm_client: secretmanager.SecretManagerServiceClient | None = None,
710
- ) -> dict[str, Any] | None:
711
- """Query aggregate monitoring stats for a rollout.
712
-
713
- Returns counts of total actors, actors with any pin, and actors pinned
714
- specifically to this rollout.
715
-
716
- Args:
717
- rollout_id: Rollout UUID to get stats for
718
- gsm_client: GCP Secret Manager client. If None, a new client will be instantiated.
719
-
720
- Returns:
721
- Dict with rollout_id, actor_definition_id, num_actors, num_actors_pinned,
722
- num_pinned_to_rollout, or None if rollout not found
723
- """
724
- rows = _run_sql_query(
725
- SELECT_ROLLOUT_AGGREGATE_STATS,
726
- parameters={"rollout_id": rollout_id},
727
- query_name="SELECT_ROLLOUT_AGGREGATE_STATS",
728
- gsm_client=gsm_client,
729
- )
730
- # The SQL query uses scalar subqueries that always return one row,
731
- # but with NULL values if the rollout doesn't exist
732
- if rows and rows[0].get("rollout_id") is not None:
733
- return rows[0]
734
- return None
735
-
736
-
737
- def query_rollout_actor_sync_stats(
738
- rollout_id: str,
739
- days_back: int = 7,
740
- *,
741
- gsm_client: secretmanager.SecretManagerServiceClient | None = None,
742
- ) -> list[dict[str, Any]]:
743
- """Query per-actor sync stats for actors pinned to a rollout.
744
-
745
- Returns succeeded/failed job counts and connection counts for each actor
746
- that is pinned to the specified rollout.
747
-
748
- Args:
749
- rollout_id: Rollout UUID to get actor stats for
750
- days_back: Number of days to look back for job stats (default: 7)
751
- gsm_client: GCP Secret Manager client. If None, a new client will be instantiated.
752
-
753
- Returns:
754
- List of dicts with actor_id, num_succeeded, num_failed, num_connections
755
- """
756
- cutoff_date = datetime.now(timezone.utc) - timedelta(days=days_back)
757
- return _run_sql_query(
758
- SELECT_ROLLOUT_ACTOR_SYNC_STATS,
759
- parameters={"rollout_id": rollout_id, "cutoff_date": cutoff_date},
760
- query_name="SELECT_ROLLOUT_ACTOR_SYNC_STATS",
761
- gsm_client=gsm_client,
762
- )
@@ -1217,94 +1217,3 @@ SELECT_ACTORS_PINNED_TO_ROLLOUT = sqlalchemy.text(
1217
1217
  scoped_configuration.created_at DESC
1218
1218
  """
1219
1219
  )
1220
-
1221
- # Get rollout monitoring stats: aggregate counts for a rollout
1222
- # Returns: total actors for connector, actors with any pin, actors pinned to this rollout
1223
- SELECT_ROLLOUT_AGGREGATE_STATS = sqlalchemy.text(
1224
- """
1225
- WITH rollout_info AS (
1226
- SELECT
1227
- cr.id AS rollout_id,
1228
- cr.actor_definition_id,
1229
- cr.release_candidate_version_id
1230
- FROM connector_rollout cr
1231
- WHERE cr.id = :rollout_id
1232
- ),
1233
- total_actors AS (
1234
- SELECT COUNT(*) AS num_actors
1235
- FROM actor
1236
- WHERE actor.actor_definition_id = (SELECT actor_definition_id FROM rollout_info)
1237
- AND actor.tombstone = false
1238
- ),
1239
- pinned_actors AS (
1240
- SELECT COUNT(DISTINCT scoped_configuration.scope_id) AS num_pinned
1241
- FROM scoped_configuration
1242
- JOIN actor ON scoped_configuration.scope_id = actor.id
1243
- WHERE scoped_configuration.key = 'connector_version'
1244
- AND scoped_configuration.scope_type = 'actor'
1245
- AND actor.actor_definition_id = (SELECT actor_definition_id FROM rollout_info)
1246
- AND actor.tombstone = false
1247
- ),
1248
- rollout_pinned_actors AS (
1249
- SELECT COUNT(DISTINCT scoped_configuration.scope_id) AS num_rollout_pinned
1250
- FROM scoped_configuration
1251
- WHERE scoped_configuration.key = 'connector_version'
1252
- AND scoped_configuration.scope_type = 'actor'
1253
- AND scoped_configuration.origin = :rollout_id
1254
- )
1255
- SELECT
1256
- (SELECT rollout_id FROM rollout_info) AS rollout_id,
1257
- (SELECT actor_definition_id FROM rollout_info) AS actor_definition_id,
1258
- (SELECT num_actors FROM total_actors) AS num_actors,
1259
- (SELECT num_pinned FROM pinned_actors) AS num_actors_pinned,
1260
- (SELECT num_rollout_pinned FROM rollout_pinned_actors) AS num_pinned_to_rollout
1261
- """
1262
- )
1263
-
1264
- # Get per-actor sync stats for actors pinned to a rollout
1265
- # Returns: actor_id, succeeded count, failed count, connection count
1266
- SELECT_ROLLOUT_ACTOR_SYNC_STATS = sqlalchemy.text(
1267
- """
1268
- WITH rollout_actors AS (
1269
- SELECT DISTINCT
1270
- scoped_configuration.scope_id AS actor_id
1271
- FROM scoped_configuration
1272
- WHERE scoped_configuration.key = 'connector_version'
1273
- AND scoped_configuration.scope_type = 'actor'
1274
- AND scoped_configuration.origin = :rollout_id
1275
- ),
1276
- actor_connections AS (
1277
- SELECT
1278
- ra.actor_id,
1279
- COUNT(DISTINCT c.id) AS num_connections
1280
- FROM rollout_actors ra
1281
- LEFT JOIN connection c
1282
- ON c.source_id = ra.actor_id OR c.destination_id = ra.actor_id
1283
- WHERE c.status != 'deprecated' OR c.status IS NULL
1284
- GROUP BY ra.actor_id
1285
- ),
1286
- actor_job_stats AS (
1287
- SELECT
1288
- ra.actor_id,
1289
- COUNT(CASE WHEN j.status = 'succeeded' THEN 1 END) AS num_succeeded,
1290
- COUNT(CASE WHEN j.status = 'failed' THEN 1 END) AS num_failed
1291
- FROM rollout_actors ra
1292
- LEFT JOIN connection c
1293
- ON c.source_id = ra.actor_id OR c.destination_id = ra.actor_id
1294
- LEFT JOIN jobs j
1295
- ON j.scope = c.id::text
1296
- AND j.config_type = 'sync'
1297
- AND j.created_at >= :cutoff_date
1298
- GROUP BY ra.actor_id
1299
- )
1300
- SELECT
1301
- ra.actor_id,
1302
- COALESCE(ajs.num_succeeded, 0) AS num_succeeded,
1303
- COALESCE(ajs.num_failed, 0) AS num_failed,
1304
- COALESCE(ac.num_connections, 0) AS num_connections
1305
- FROM rollout_actors ra
1306
- LEFT JOIN actor_job_stats ajs ON ra.actor_id = ajs.actor_id
1307
- LEFT JOIN actor_connections ac ON ra.actor_id = ac.actor_id
1308
- ORDER BY COALESCE(ajs.num_failed, 0) DESC, COALESCE(ajs.num_succeeded, 0) DESC
1309
- """
1310
- )