SIENTIAPDE-1163
refactor: update notification handling in activities to include metadata in notifications, enhancing context for error reporting and success messages; update requirements to use version 1.3.0 of the sientia-dataops-library
This commit is contained in:
@@ -258,6 +258,8 @@ class Formatters(BaseActivity):
|
||||
|
||||
self.logger.info("Creating slot config...")
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
current_slot_config = input_data['current_slot_config']
|
||||
slot_config = input_data['slot_config']
|
||||
to_delete = []
|
||||
@@ -280,21 +282,23 @@ class Formatters(BaseActivity):
|
||||
|
||||
return output
|
||||
|
||||
def send_success_report(self, message: str, notification_id: str) -> None:
|
||||
self.notification_handler.build_and_send_notification(
|
||||
notification_id,
|
||||
message,
|
||||
"report_orchestration",
|
||||
NotificationLevel.INFO
|
||||
def send_success_report(self, metadata: dict[str, Any], message: str, notification_id: str) -> None:
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id=notification_id,
|
||||
message=message,
|
||||
block="report_orchestration",
|
||||
level=NotificationLevel.INFO
|
||||
)
|
||||
|
||||
def send_error_report(self, message: str, notification_id: str,
|
||||
def send_error_report(self, metadata: dict[str, Any], message: str, notification_id: str,
|
||||
attachment: dict[str, Any]) -> None:
|
||||
self.notification_handler.build_and_send_notification(
|
||||
notification_id,
|
||||
message,
|
||||
"report_orchestration",
|
||||
NotificationLevel.ERROR,
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id=notification_id,
|
||||
message=message,
|
||||
block="report_orchestration",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=json.dumps(attachment, indent=4, sort_keys=True)
|
||||
)
|
||||
|
||||
@@ -332,6 +336,8 @@ class Formatters(BaseActivity):
|
||||
|
||||
self.logger.info("Reporting orchestration...")
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
created_schedules = input_data['created_schedules']
|
||||
updated_schedules = input_data['updated_schedules']
|
||||
deleted_schedules = input_data['deleted_schedules']
|
||||
@@ -343,15 +349,17 @@ class Formatters(BaseActivity):
|
||||
|
||||
if len(success_keys) > 0:
|
||||
self.send_success_report(
|
||||
f"Created schedules: \n {', '.join(success_keys)}",
|
||||
"REPORT_ORCHESTRATION_CREATED_SCHEDULES"
|
||||
metadata=metadata,
|
||||
message=f"Created schedules: \n {', '.join(success_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_CREATED_SCHEDULES"
|
||||
)
|
||||
|
||||
if len(error_keys) > 0:
|
||||
self.send_error_report(
|
||||
f"Failed to create schedules: \n {', '.join(error_keys)}",
|
||||
"REPORT_ORCHESTRATION_CREATED_SCHEDULES",
|
||||
created_schedules
|
||||
metadata=metadata,
|
||||
message=f"Failed to create schedules: \n {', '.join(error_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_CREATED_SCHEDULES",
|
||||
attachment=created_schedules
|
||||
)
|
||||
|
||||
# Send report for updated schedules
|
||||
@@ -361,15 +369,17 @@ class Formatters(BaseActivity):
|
||||
|
||||
if len(success_keys) > 0:
|
||||
self.send_success_report(
|
||||
f"Updated schedules: \n {', '.join(success_keys)}",
|
||||
"REPORT_ORCHESTRATION_UPDATED_SCHEDULES"
|
||||
metadata=metadata,
|
||||
message=f"Updated schedules: \n {', '.join(success_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_UPDATED_SCHEDULES"
|
||||
)
|
||||
|
||||
if len(error_keys) > 0:
|
||||
self.send_error_report(
|
||||
f"Failed to update schedules: \n {', '.join(error_keys)}",
|
||||
"REPORT_ORCHESTRATION_UPDATED_SCHEDULES",
|
||||
updated_schedules
|
||||
metadata=metadata,
|
||||
message=f"Failed to update schedules: \n {', '.join(error_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_UPDATED_SCHEDULES",
|
||||
attachment=updated_schedules
|
||||
)
|
||||
|
||||
if len(deleted_schedules) > 0:
|
||||
@@ -378,15 +388,17 @@ class Formatters(BaseActivity):
|
||||
|
||||
if len(success_keys) > 0:
|
||||
self.send_success_report(
|
||||
f"Deleted schedules: \n {', '.join(success_keys)}",
|
||||
"REPORT_ORCHESTRATION_DELETED_SCHEDULES"
|
||||
metadata=metadata,
|
||||
message=f"Deleted schedules: \n {', '.join(success_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_DELETED_SCHEDULES"
|
||||
)
|
||||
|
||||
if len(error_keys) > 0:
|
||||
self.send_error_report(
|
||||
f"Failed to delete schedules: \n {', '.join(error_keys)}",
|
||||
"REPORT_ORCHESTRATION_DELETED_SCHEDULES",
|
||||
deleted_schedules
|
||||
metadata=metadata,
|
||||
message=f"Failed to delete schedules: \n {', '.join(error_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_DELETED_SCHEDULES",
|
||||
attachment=deleted_schedules
|
||||
)
|
||||
|
||||
@activity.defn(name="report_slot_orchestration")
|
||||
@@ -404,6 +416,8 @@ class Formatters(BaseActivity):
|
||||
|
||||
self.logger.info("Reporting orchestration...")
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
inserted_slots = input_data['inserted_slots']
|
||||
deleted_slots = input_data['deleted_slots']
|
||||
|
||||
@@ -412,15 +426,17 @@ class Formatters(BaseActivity):
|
||||
|
||||
if len(success_keys) > 0:
|
||||
self.send_success_report(
|
||||
f"Inserted slots: \n {', '.join(success_keys)}",
|
||||
"REPORT_ORCHESTRATION_INSERTED_SLOTS"
|
||||
metadata=metadata,
|
||||
message=f"Inserted slots: \n {', '.join(success_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_INSERTED_SLOTS"
|
||||
)
|
||||
|
||||
if len(error_keys) > 0:
|
||||
self.send_error_report(
|
||||
f"Failed to insert slots: \n {', '.join(error_keys)}",
|
||||
"REPORT_ORCHESTRATION_INSERTED_SLOTS",
|
||||
inserted_slots
|
||||
metadata=metadata,
|
||||
message=f"Failed to insert slots: \n {', '.join(error_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_INSERTED_SLOTS",
|
||||
attachment=inserted_slots
|
||||
)
|
||||
|
||||
if len(deleted_slots) > 0:
|
||||
@@ -428,13 +444,15 @@ class Formatters(BaseActivity):
|
||||
|
||||
if len(success_keys) > 0:
|
||||
self.send_success_report(
|
||||
f"Deleted slots: \n {', '.join(success_keys)}",
|
||||
"REPORT_ORCHESTRATION_DELETED_SLOTS"
|
||||
metadata=metadata,
|
||||
message=f"Deleted slots: \n {', '.join(success_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_DELETED_SLOTS"
|
||||
)
|
||||
|
||||
if len(error_keys) > 0:
|
||||
self.send_error_report(
|
||||
f"Failed to delete slots: \n {', '.join(error_keys)}",
|
||||
"REPORT_ORCHESTRATION_DELETED_SLOTS",
|
||||
deleted_slots
|
||||
metadata=metadata,
|
||||
message=f"Failed to delete slots: \n {', '.join(error_keys)}",
|
||||
notification_id="REPORT_ORCHESTRATION_DELETED_SLOTS",
|
||||
attachment=deleted_slots
|
||||
)
|
||||
|
||||
@@ -92,6 +92,7 @@ class MongoDB(BaseActivity):
|
||||
"""
|
||||
|
||||
query = input_data.get("query", {})
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
collection_name = query.get("collection")
|
||||
if not collection_name:
|
||||
@@ -120,7 +121,8 @@ class MongoDB(BaseActivity):
|
||||
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.notification_handler.build_and_send_notification(
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="MONGODB_QUERY_ERROR",
|
||||
message=f"Failed to execute MongoDB query: {e}",
|
||||
block="load_query_from_mongodb",
|
||||
@@ -146,6 +148,7 @@ class MongoDB(BaseActivity):
|
||||
"""
|
||||
|
||||
query = input_data.get("query", {})
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
collection_name = query.get("collection")
|
||||
if not collection_name:
|
||||
@@ -177,7 +180,8 @@ class MongoDB(BaseActivity):
|
||||
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.notification_handler.build_and_send_notification(
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="MONGODB_AGGREGATION_ERROR",
|
||||
message=f"Failed to execute MongoDB aggregation: {e}",
|
||||
block="aggregate_documents_in_mongodb",
|
||||
@@ -196,6 +200,7 @@ class MongoDB(BaseActivity):
|
||||
- updated_pipelines (list): List of updated pipelines.
|
||||
"""
|
||||
updated_pipelines = input_data.get("updated_pipelines", [])
|
||||
metadata = input_data.get("metadata", {})
|
||||
now = datetime.now().strftime(DEFAULT_DATE_FORMAT)
|
||||
collection = self.database["orchestrated_schedules"]
|
||||
|
||||
@@ -205,10 +210,24 @@ class MongoDB(BaseActivity):
|
||||
for pipeline in updated_pipelines if pipeline["success"]
|
||||
]
|
||||
data_filter = {"$or": argument} if argument else {}
|
||||
collection.update_many(
|
||||
data_filter,
|
||||
{"$set": {"updated_at": now}}
|
||||
)
|
||||
|
||||
try:
|
||||
collection.update_many(
|
||||
data_filter,
|
||||
{"$set": {"updated_at": now}}
|
||||
)
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="MONGODB_UPDATE_ERROR",
|
||||
message=f"Failed to update pipelines timestamps: {e}",
|
||||
block="update_pipelines_timestamps",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
@activity.defn(name="create_pipelines_timestamps")
|
||||
async def create_pipelines_timestamps(self, input_data: dict[str, Any]) -> None:
|
||||
@@ -218,6 +237,7 @@ class MongoDB(BaseActivity):
|
||||
- created_pipelines (list): List of created pipelines.
|
||||
"""
|
||||
created_pipelines = input_data.get("created_pipelines", [])
|
||||
metadata = input_data.get("metadata", {})
|
||||
collection = self.database["orchestrated_schedules"]
|
||||
|
||||
now = datetime.now().strftime(DEFAULT_DATE_FORMAT)
|
||||
@@ -229,7 +249,21 @@ class MongoDB(BaseActivity):
|
||||
for pipeline in created_pipelines if pipeline["success"]
|
||||
]
|
||||
data_filter = argument if argument else {}
|
||||
collection.insert_many(data_filter)
|
||||
|
||||
try:
|
||||
collection.insert_many(data_filter)
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="MONGODB_INSERT_ERROR",
|
||||
message=f"Failed to create pipelines timestamps: {e}",
|
||||
block="create_pipelines_timestamps",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
@activity.defn(name="delete_pipelines_timestamps")
|
||||
async def delete_pipelines_timestamps(self, input_data: dict[str, Any]) -> None:
|
||||
@@ -239,6 +273,7 @@ class MongoDB(BaseActivity):
|
||||
- deleted_pipelines (list): List of deleted pipelines.
|
||||
"""
|
||||
deleted_pipelines = input_data.get("deleted_pipelines", [])
|
||||
metadata = input_data.get("metadata", {})
|
||||
collection = self.database["orchestrated_schedules"]
|
||||
|
||||
argument = [
|
||||
@@ -248,4 +283,17 @@ class MongoDB(BaseActivity):
|
||||
]
|
||||
data_filter = {"$or": argument} if argument else {}
|
||||
|
||||
collection.delete_many(data_filter)
|
||||
try:
|
||||
collection.delete_many(data_filter)
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="MONGODB_DELETE_ERROR",
|
||||
message=f"Failed to delete pipelines timestamps: {e}",
|
||||
block="delete_pipelines_timestamps",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
@@ -2,10 +2,12 @@ from temporalio import activity, workflow
|
||||
|
||||
with workflow.unsafe.imports_passed_through():
|
||||
from typing import Any
|
||||
import traceback
|
||||
import json
|
||||
from logging import Logger
|
||||
from sientia_do.temporal.activities.redis_base import Redis
|
||||
from sientia_do.notifications.handlers import CoreNotificationHandler as NotificationHandler
|
||||
from sientia_do.notifications.models import NotificationLevel
|
||||
|
||||
|
||||
class SlotManager(Redis):
|
||||
@@ -18,7 +20,7 @@ class SlotManager(Redis):
|
||||
password, logger, notification_handler)
|
||||
|
||||
@activity.defn(name="load_opc_slots")
|
||||
async def load_opc_slots(self) -> dict[str, Any]:
|
||||
async def load_opc_slots(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
Load all OPC slots from Redis
|
||||
|
||||
@@ -26,32 +28,45 @@ class SlotManager(Redis):
|
||||
dict[str, Any]: A dictionary of OPC slots
|
||||
"""
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
self.logger.info("Loading OPC slots...")
|
||||
|
||||
opc_slots = {}
|
||||
|
||||
slot_keys = self.redis_client.keys("slot:opc_tags:*")
|
||||
try:
|
||||
|
||||
self.logger.debug(f"Slot keys: {slot_keys}")
|
||||
slot_keys = self.redis_client.keys("slot:opc_tags:*")
|
||||
|
||||
if slot_keys:
|
||||
if isinstance(slot_keys[0], bytes):
|
||||
decoded_keys = [key.decode('utf-8') for key in slot_keys]
|
||||
else:
|
||||
decoded_keys = slot_keys
|
||||
self.logger.debug(f"Slot keys: {slot_keys}")
|
||||
|
||||
for key in decoded_keys:
|
||||
opc_slots[key] = self.get(key)
|
||||
if slot_keys:
|
||||
if isinstance(slot_keys[0], bytes):
|
||||
decoded_keys = [key.decode('utf-8') for key in slot_keys]
|
||||
else:
|
||||
decoded_keys = slot_keys
|
||||
|
||||
for key in decoded_keys:
|
||||
opc_slots[key] = self.get(key)
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="REDIS_GET_ERROR",
|
||||
message=f"Failed to load OPC slots: {e}",
|
||||
block="load_opc_slots",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
self.logger.info(f"Loaded {len(opc_slots)} OPC slots")
|
||||
|
||||
self.logger.debug(
|
||||
f"Loaded: \n {json.dumps(opc_slots, indent=4, sort_keys=True)}")
|
||||
|
||||
return opc_slots
|
||||
|
||||
@activity.defn(name="load_active_ingestors")
|
||||
async def load_active_ingestors(self) -> list[str]:
|
||||
async def load_active_ingestors(self, input_data: dict[str, Any]) -> list[str]:
|
||||
"""
|
||||
Load all active ingestors from Redis
|
||||
|
||||
@@ -59,23 +74,40 @@ class SlotManager(Redis):
|
||||
list[str]: A list of active ingestors
|
||||
"""
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
self.logger.info("Loading active ingestors...")
|
||||
|
||||
active_ingestors = self.redis_client.keys("heartbeat:ingestor:*")
|
||||
try:
|
||||
|
||||
self.logger.info(f"Loaded {len(active_ingestors)} active ingestors")
|
||||
active_ingestors = self.redis_client.keys("heartbeat:ingestor:*")
|
||||
|
||||
self.logger.debug(f"Active ingestors: \n {active_ingestors}")
|
||||
self.logger.info(
|
||||
f"Loaded {len(active_ingestors)} active ingestors")
|
||||
|
||||
ingestors = []
|
||||
self.logger.debug(f"Active ingestors: \n {active_ingestors}")
|
||||
|
||||
for ingestor in active_ingestors:
|
||||
if isinstance(ingestor, bytes):
|
||||
ingestors.append(ingestor.decode('utf-8'))
|
||||
else:
|
||||
ingestors.append(ingestor)
|
||||
ingestors = []
|
||||
|
||||
return ingestors
|
||||
for ingestor in active_ingestors:
|
||||
if isinstance(ingestor, bytes):
|
||||
ingestors.append(ingestor.decode('utf-8'))
|
||||
else:
|
||||
ingestors.append(ingestor)
|
||||
|
||||
return ingestors
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="REDIS_GET_ERROR",
|
||||
message=f"Failed to load active ingestors: {e}",
|
||||
block="load_active_ingestors",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
@activity.defn(name="update_slots")
|
||||
async def update_slots(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
@@ -4,10 +4,12 @@ from temporalio.client import (
|
||||
from temporalio.common import SearchAttributeKey, SearchAttributePair, TypedSearchAttributes
|
||||
|
||||
with workflow.unsafe.imports_passed_through():
|
||||
import traceback
|
||||
from typing import Any
|
||||
from logging import Logger
|
||||
from sientia_do.notifications.handlers import CoreNotificationHandler as NotificationHandler
|
||||
from sientia_do.temporal.activities.base import BaseActivity
|
||||
from sientia_do.notifications.models import NotificationLevel
|
||||
from google.protobuf.json_format import MessageToDict
|
||||
import base64
|
||||
from datetime import timedelta
|
||||
@@ -62,7 +64,7 @@ class TemporalManager(BaseActivity):
|
||||
}
|
||||
|
||||
@activity.defn(name="load_schedule")
|
||||
async def load_schedule(self) -> dict[str, Any]:
|
||||
async def load_schedule(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
Load all orchestrated schedules from Temporal. Filters by search attribute
|
||||
"Orchestrated" set to "true" and returns a dictionary of schedule_id:
|
||||
@@ -72,50 +74,67 @@ class TemporalManager(BaseActivity):
|
||||
dict[str, Any]: A dictionary of orchestrated schedules
|
||||
"""
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
self.logger.info("Getting orchestrated schedules...")
|
||||
|
||||
orchestrated_schedules = {}
|
||||
|
||||
for namespace, client in self.temporal_clients.items():
|
||||
orchestrated_schedules[namespace] = {}
|
||||
try:
|
||||
|
||||
self.logger.info(
|
||||
f"Getting orchestrated schedules for {namespace}")
|
||||
for namespace, client in self.temporal_clients.items():
|
||||
orchestrated_schedules[namespace] = {}
|
||||
|
||||
async for schedule in await client.list_schedules():
|
||||
search_attrs = getattr(schedule, "search_attributes", {})
|
||||
if search_attrs.get("orchestrated", ["false"]) == ["true"]:
|
||||
schedule_id = schedule.id
|
||||
self.logger.info(
|
||||
f"Getting orchestrated schedules for {namespace}")
|
||||
|
||||
self.logger.debug(f"Schedule id: {schedule_id}")
|
||||
async for schedule in await client.list_schedules():
|
||||
search_attrs = getattr(schedule, "search_attributes", {})
|
||||
if search_attrs.get("orchestrated", ["false"]) == ["true"]:
|
||||
schedule_id = schedule.id
|
||||
|
||||
handle = client.get_schedule_handle(
|
||||
schedule_id)
|
||||
self.logger.debug(f"Schedule id: {schedule_id}")
|
||||
|
||||
self.logger.debug("Handle acquired")
|
||||
handle = client.get_schedule_handle(
|
||||
schedule_id)
|
||||
|
||||
self.schedule_handles[namespace][schedule_id] = handle
|
||||
self.logger.debug("Handle acquired")
|
||||
|
||||
self.logger.debug("Describing schedule...")
|
||||
self.schedule_handles[namespace][schedule_id] = handle
|
||||
|
||||
desc = await handle.describe(
|
||||
rpc_timeout=timedelta(seconds=60)
|
||||
)
|
||||
self.logger.debug("Describing schedule...")
|
||||
|
||||
self.logger.debug("Parsing args...")
|
||||
desc = await handle.describe(
|
||||
rpc_timeout=timedelta(seconds=60)
|
||||
)
|
||||
|
||||
for arg in desc.schedule.action.args:
|
||||
data = MessageToDict(arg)['data']
|
||||
data = base64.b64decode(data).decode('utf-8')
|
||||
self.logger.debug("Parsing args...")
|
||||
|
||||
frequency = desc.schedule.spec.intervals[0].every.seconds
|
||||
for arg in desc.schedule.action.args:
|
||||
data = MessageToDict(arg)['data']
|
||||
data = base64.b64decode(data).decode('utf-8')
|
||||
|
||||
orchestrated_schedules[namespace][schedule_id] = {
|
||||
'frequency': frequency,
|
||||
'data': json.loads(data),
|
||||
}
|
||||
frequency = desc.schedule.spec.intervals[0].every.seconds
|
||||
|
||||
await sleep(0.1)
|
||||
orchestrated_schedules[namespace][schedule_id] = {
|
||||
'frequency': frequency,
|
||||
'data': json.loads(data),
|
||||
}
|
||||
|
||||
await sleep(0.1)
|
||||
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="TEMPORAL_LOAD_SCHEDULE_ERROR",
|
||||
message=f"Failed to load orchestrated schedules: {e}",
|
||||
block="load_schedule",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
self.logger.info(
|
||||
f"Found {len(orchestrated_schedules[self.scouter_namespace]) + len(orchestrated_schedules[self.laborious_namespace])} orchestrated schedules")
|
||||
@@ -137,27 +156,43 @@ class TemporalManager(BaseActivity):
|
||||
"""
|
||||
self.logger.info("Getting orchestrated schedules...")
|
||||
|
||||
metadata = input_data.get("metadata", {})
|
||||
|
||||
orchestrated_schedules = input_data.get('orchestrated_schedules', {})
|
||||
|
||||
for namespace, client in self.temporal_clients.items():
|
||||
schedules = orchestrated_schedules.get(namespace, {})
|
||||
try:
|
||||
schedules = orchestrated_schedules.get(namespace, {})
|
||||
|
||||
self.logger.info(
|
||||
f"Getting orchestrated schedules for {namespace}")
|
||||
self.logger.info(
|
||||
f"Getting orchestrated schedules for {namespace}")
|
||||
|
||||
async for schedule in await client.list_schedules():
|
||||
search_attrs = getattr(schedule, "search_attributes", {})
|
||||
if search_attrs.get("orchestrated", ["false"]) == ["true"]:
|
||||
schedule_id = schedule.id
|
||||
async for schedule in await client.list_schedules():
|
||||
search_attrs = getattr(schedule, "search_attributes", {})
|
||||
if search_attrs.get("orchestrated", ["false"]) == ["true"]:
|
||||
schedule_id = schedule.id
|
||||
|
||||
if schedule_id not in schedules:
|
||||
self.logger.info(
|
||||
f"Schedule {schedule_id} not found in mongo db, cleaning up")
|
||||
if schedule_id not in schedules:
|
||||
self.logger.info(
|
||||
f"Schedule {schedule_id} not found in mongo db, cleaning up")
|
||||
|
||||
handle = client.get_schedule_handle(
|
||||
schedule_id)
|
||||
handle = client.get_schedule_handle(
|
||||
schedule_id)
|
||||
|
||||
await handle.delete()
|
||||
await handle.delete()
|
||||
|
||||
except Exception as e:
|
||||
trace = traceback.format_exc()
|
||||
self.send_notification(
|
||||
metadata=metadata,
|
||||
notification_id="TEMPORAL_NORMALIZE_SCHEDULES_ERROR",
|
||||
message=f"Failed to normalize schedules: {e}",
|
||||
block="normalize_schedules",
|
||||
level=NotificationLevel.ERROR,
|
||||
attachment_content=trace
|
||||
)
|
||||
self.logger.error(trace)
|
||||
raise e
|
||||
|
||||
@activity.defn(name="create_schedules")
|
||||
async def create_schedules(self, input_data: dict[str, Any]) -> list[dict[str, Any]]:
|
||||
|
||||
@@ -14,9 +14,19 @@ class Orchestrator:
|
||||
|
||||
input_data['workflow_name'] = 'orchestrator'
|
||||
|
||||
metadata = {
|
||||
'metadata': {
|
||||
'schedule_name': input_data.get('schedule_name', 'orchestrator'),
|
||||
'model_name': '-',
|
||||
'model_id': '-',
|
||||
'workflow_name': input_data['workflow_name']
|
||||
}
|
||||
}
|
||||
|
||||
pipeline_config_handler = workflow.start_local_activity_method(
|
||||
Activities.aggregate_documents_in_mongodb,
|
||||
{
|
||||
**metadata,
|
||||
'query': input_data['pipelines_query']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -26,6 +36,7 @@ class Orchestrator:
|
||||
opc_servers_handler = workflow.start_local_activity_method(
|
||||
Activities.find_documents_in_mongodb,
|
||||
{
|
||||
**metadata,
|
||||
'query': input_data['opc_servers_query']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -35,6 +46,7 @@ class Orchestrator:
|
||||
orchestrated_schedules_handler = workflow.start_local_activity_method(
|
||||
Activities.find_documents_in_mongodb,
|
||||
{
|
||||
**metadata,
|
||||
'query': {
|
||||
'collection': 'orchestrated_schedules'
|
||||
}
|
||||
@@ -45,12 +57,18 @@ class Orchestrator:
|
||||
|
||||
current_slot_config_handler = workflow.start_local_activity_method(
|
||||
Activities.load_opc_slots,
|
||||
{
|
||||
**metadata,
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
start_to_close_timeout=timedelta(seconds=60)
|
||||
)
|
||||
|
||||
active_ingestors_handler = workflow.start_local_activity_method(
|
||||
Activities.load_active_ingestors,
|
||||
{
|
||||
**metadata,
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
start_to_close_timeout=timedelta(seconds=60)
|
||||
)
|
||||
@@ -64,6 +82,7 @@ class Orchestrator:
|
||||
formatted_orchestrated_schedules_handler = workflow.start_local_activity_method(
|
||||
Activities.format_schedule_config,
|
||||
{
|
||||
**metadata,
|
||||
'schedule_config': orchestrated_schedules
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -73,6 +92,7 @@ class Orchestrator:
|
||||
schedules_config_handler = workflow.start_local_activity_method(
|
||||
Activities.process_schedules,
|
||||
{
|
||||
**metadata,
|
||||
'pipelines': pipeline_config
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -82,6 +102,7 @@ class Orchestrator:
|
||||
slot_config_handler = workflow.start_local_activity_method(
|
||||
Activities.process_slots,
|
||||
{
|
||||
**metadata,
|
||||
'opc_servers': opc_servers,
|
||||
'active_ingestors': active_ingestors,
|
||||
'pipelines': pipeline_config,
|
||||
@@ -97,6 +118,7 @@ class Orchestrator:
|
||||
schedule_actions_handler = workflow.start_local_activity_method(
|
||||
Activities.create_schedule_config,
|
||||
{
|
||||
**metadata,
|
||||
'current_schedule_config': formatted_orchestrated_schedules,
|
||||
'schedule_config': schedules_config
|
||||
},
|
||||
@@ -107,6 +129,7 @@ class Orchestrator:
|
||||
slot_actions_handler = workflow.start_local_activity_method(
|
||||
Activities.create_slot_config,
|
||||
{
|
||||
**metadata,
|
||||
'current_slot_config': current_slot_config,
|
||||
'slot_config': slot_config
|
||||
},
|
||||
@@ -117,6 +140,7 @@ class Orchestrator:
|
||||
normalize_schedules_handler = workflow.start_local_activity_method(
|
||||
Activities.normalize_schedules,
|
||||
{
|
||||
**metadata,
|
||||
'orchestrated_schedules': formatted_orchestrated_schedules
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -130,6 +154,7 @@ class Orchestrator:
|
||||
slot_deletion_report_handler = workflow.start_activity_method(
|
||||
Activities.delete_slots,
|
||||
{
|
||||
**metadata,
|
||||
'to_delete': slot_actions['to_delete']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -139,6 +164,7 @@ class Orchestrator:
|
||||
slot_insertion_report_handler = workflow.start_activity_method(
|
||||
Activities.update_slots,
|
||||
{
|
||||
**metadata,
|
||||
'to_insert': slot_actions['to_insert']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -148,6 +174,7 @@ class Orchestrator:
|
||||
schedule_deletion_report_handler = workflow.start_activity_method(
|
||||
Activities.delete_schedules,
|
||||
{
|
||||
**metadata,
|
||||
'schedules': schedule_actions['to_delete']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -157,6 +184,7 @@ class Orchestrator:
|
||||
schedule_insertion_report_handler = workflow.start_activity_method(
|
||||
Activities.create_schedules,
|
||||
{
|
||||
**metadata,
|
||||
'schedules': schedule_actions['to_create']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -166,6 +194,7 @@ class Orchestrator:
|
||||
schedule_update_report_handler = workflow.start_activity_method(
|
||||
Activities.update_schedules,
|
||||
{
|
||||
**metadata,
|
||||
'schedules': schedule_actions['to_update']
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -183,6 +212,7 @@ class Orchestrator:
|
||||
schedule_report_handler = workflow.start_activity_method(
|
||||
Activities.report_schedule_orchestration,
|
||||
{
|
||||
**metadata,
|
||||
'created_schedules': schedule_insertion_report,
|
||||
'updated_schedules': schedule_update_report,
|
||||
'deleted_schedules': schedule_deletion_report
|
||||
@@ -196,6 +226,7 @@ class Orchestrator:
|
||||
slot_report_handler = workflow.start_activity_method(
|
||||
Activities.report_slot_orchestration,
|
||||
{
|
||||
**metadata,
|
||||
'inserted_slots': slot_insertion_report,
|
||||
'deleted_slots': slot_deletion_report
|
||||
},
|
||||
@@ -208,6 +239,7 @@ class Orchestrator:
|
||||
update_pipelines_timestamps_handler = workflow.start_activity_method(
|
||||
Activities.update_pipelines_timestamps,
|
||||
{
|
||||
**metadata,
|
||||
'updated_pipelines': schedule_update_report
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -219,6 +251,7 @@ class Orchestrator:
|
||||
create_pipelines_timestamps_handler = workflow.start_activity_method(
|
||||
Activities.create_pipelines_timestamps,
|
||||
{
|
||||
**metadata,
|
||||
'created_pipelines': schedule_insertion_report
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
@@ -230,6 +263,7 @@ class Orchestrator:
|
||||
delete_pipelines_timestamps_handler = workflow.start_activity_method(
|
||||
Activities.delete_pipelines_timestamps,
|
||||
{
|
||||
**metadata,
|
||||
'deleted_pipelines': schedule_deletion_report
|
||||
},
|
||||
retry_policy=retry_policy,
|
||||
|
||||
Reference in New Issue
Block a user