SIENTIAPDE-1184
refactor: enhance shutdown procedures and documentation across activities - Added shutdown methods to MongoDB and Email classes to ensure proper resource cleanup. - Updated docstrings for shutdown methods to clarify their purpose and functionality. - Enhanced documentation for various methods across multiple classes, improving clarity on parameters and return values. - Improved the main function and other utility functions with detailed docstrings for better understanding and maintainability.
This commit is contained in:
@@ -82,4 +82,9 @@ class Activities( # Couchbase,
|
|||||||
notification_handler=notification_handler)
|
notification_handler=notification_handler)
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
|
"""
|
||||||
|
Shutdown the MongoDB connection and clean up resources.
|
||||||
|
"""
|
||||||
MongoDB.shutdown(self)
|
MongoDB.shutdown(self)
|
||||||
|
Postgres.close(self)
|
||||||
|
Email.shutdown(self)
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ class Email(BaseActivity):
|
|||||||
logger=logger,
|
logger=logger,
|
||||||
notification_handler=notification_handler)
|
notification_handler=notification_handler)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
"""
|
||||||
|
Shutdown the Email connection and clean up resources.
|
||||||
|
"""
|
||||||
|
self.server.quit()
|
||||||
|
|
||||||
@activity.defn(name="build_email_html")
|
@activity.defn(name="build_email_html")
|
||||||
async def build_email_html(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
async def build_email_html(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
@@ -105,9 +111,15 @@ class Email(BaseActivity):
|
|||||||
|
|
||||||
def try_send_email(self, msg: MIMEMultipart, receivers: str):
|
def try_send_email(self, msg: MIMEMultipart, receivers: str):
|
||||||
"""
|
"""
|
||||||
Sends an email to the receivers.
|
Sends an email to the receivers with automatic reconnection handling.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (MIMEMultipart): The email message to send.
|
||||||
|
receivers (str): Comma-separated list of email addresses to send to.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Exception: If email sending fails after reconnection attempts.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.server.sendmail(
|
self.server.sendmail(
|
||||||
self.sender_email, receivers, msg.as_string())
|
self.sender_email, receivers, msg.as_string())
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class MongoDB(BaseActivity):
|
|||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
"""
|
"""
|
||||||
Close the MongoDB client connection.
|
Shutdown the MongoDB connection and clean up resources.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if self.client:
|
if self.client:
|
||||||
@@ -81,6 +81,16 @@ class MongoDB(BaseActivity):
|
|||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def find(self, collection_name: str, filters: dict[str, Any]) -> list[dict[str, Any]]:
|
def find(self, collection_name: str, filters: dict[str, Any]) -> list[dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Find documents in a MongoDB collection based on the provided filters.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
collection_name (str): The name of the collection to search in.
|
||||||
|
filters (dict[str, Any]): The query filters to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[dict[str, Any]]: List of documents matching the filters, with _id fields removed.
|
||||||
|
"""
|
||||||
collection = self.database[collection_name]
|
collection = self.database[collection_name]
|
||||||
|
|
||||||
documents = list(collection.find(filters, {"_id": 0}))
|
documents = list(collection.find(filters, {"_id": 0}))
|
||||||
|
|||||||
@@ -202,6 +202,14 @@ class SlotManager(Redis):
|
|||||||
async def get_last_data_timestamp(self, input_data: dict[str, Any]) -> str | None:
|
async def get_last_data_timestamp(self, input_data: dict[str, Any]) -> str | None:
|
||||||
"""
|
"""
|
||||||
Gets the last data timestamp from redis.
|
Gets the last data timestamp from redis.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_data (dict[str, Any]): The input data containing:
|
||||||
|
- metadata (dict): Metadata for logging purposes.
|
||||||
|
- mail_type (str): The type of mail to get timestamp for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | None: The last data timestamp as a string, or None if no timestamp exists.
|
||||||
"""
|
"""
|
||||||
metadata = input_data['metadata']
|
metadata = input_data['metadata']
|
||||||
key = f"notification_last_timestamp:{input_data['mail_type']}"
|
key = f"notification_last_timestamp:{input_data['mail_type']}"
|
||||||
@@ -233,6 +241,15 @@ class SlotManager(Redis):
|
|||||||
async def put_last_data_timestamp(self, input_data: dict[str, Any]):
|
async def put_last_data_timestamp(self, input_data: dict[str, Any]):
|
||||||
"""
|
"""
|
||||||
Puts the last data timestamp into redis.
|
Puts the last data timestamp into redis.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_data (dict[str, Any]): The input data containing:
|
||||||
|
- metadata (dict): Metadata for logging purposes.
|
||||||
|
- data (list[dict]): The data to extract timestamp from.
|
||||||
|
- mail_type (str): The type of mail to store timestamp for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | None: The last data timestamp that was stored, or None if no data exists.
|
||||||
"""
|
"""
|
||||||
metadata = input_data['metadata']
|
metadata = input_data['metadata']
|
||||||
key = f"notification_last_timestamp:{input_data['mail_type']}"
|
key = f"notification_last_timestamp:{input_data['mail_type']}"
|
||||||
@@ -270,7 +287,18 @@ class SlotManager(Redis):
|
|||||||
@activity.defn(name="filter_notification_alerts")
|
@activity.defn(name="filter_notification_alerts")
|
||||||
async def filter_notification_alerts(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
async def filter_notification_alerts(self, input_data: dict[str, Any]) -> dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Filter notification alerts
|
Filter notification alerts based on sending configurations and notification package.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_data (dict[str, Any]): The input data containing:
|
||||||
|
- metadata (dict): Metadata for logging purposes.
|
||||||
|
- notification_package (list): The package of notifications to filter.
|
||||||
|
- sending_configs (list): The configurations for sending notifications.
|
||||||
|
Each config should have 'group_name', 'contents', and optionally 'ignore' fields.
|
||||||
|
- notification_ttl (int): Time to live for notifications in seconds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: The filtered receiver groups with their notifications.
|
||||||
"""
|
"""
|
||||||
metadata = input_data['metadata']
|
metadata = input_data['metadata']
|
||||||
notification_package = input_data['notification_package']
|
notification_package = input_data['notification_package']
|
||||||
@@ -330,7 +358,13 @@ class SlotManager(Redis):
|
|||||||
@activity.defn(name="store_notification_cache")
|
@activity.defn(name="store_notification_cache")
|
||||||
async def store_notification_cache(self, input_data: dict[str, Any]) -> None:
|
async def store_notification_cache(self, input_data: dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
Store notification cache
|
Store notification cache in Redis to track recently sent notifications.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_data (dict[str, Any]): The input data containing:
|
||||||
|
- metadata (dict): Metadata for logging purposes.
|
||||||
|
- log_report (list[dict]): The log report containing notification statuses.
|
||||||
|
- sent_ttl (int): Time to live for sent notification cache in seconds.
|
||||||
"""
|
"""
|
||||||
metadata = input_data['metadata']
|
metadata = input_data['metadata']
|
||||||
log_report = DataFrame(input_data['log_report'])
|
log_report = DataFrame(input_data['log_report'])
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ class TemporalManager(BaseActivity):
|
|||||||
notification_handler=notification_handler)
|
notification_handler=notification_handler)
|
||||||
|
|
||||||
async def connect_to_temporal(self):
|
async def connect_to_temporal(self):
|
||||||
|
"""
|
||||||
|
Connect to Temporal server namespaces for scouter and laborious workflows.
|
||||||
|
Creates client connections to both namespaces and stores them for later use.
|
||||||
|
"""
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
f"Connecting to Temporal side namespaces at {self.temporal_host}")
|
f"Connecting to Temporal side namespaces at {self.temporal_host}")
|
||||||
self.logger.info(f"Scouter namespace: {self.scouter_namespace}")
|
self.logger.info(f"Scouter namespace: {self.scouter_namespace}")
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ from os import getenv
|
|||||||
|
|
||||||
|
|
||||||
def build_redis_config():
|
def build_redis_config():
|
||||||
|
"""
|
||||||
|
Build Redis configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Redis configuration with host, port, username, and password.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
'host': getenv('REDIS_HOST', 'localhost'),
|
'host': getenv('REDIS_HOST', 'localhost'),
|
||||||
'port': int(getenv('REDIS_PORT', '6379')),
|
'port': int(getenv('REDIS_PORT', '6379')),
|
||||||
@@ -11,6 +17,12 @@ def build_redis_config():
|
|||||||
|
|
||||||
|
|
||||||
def build_mongodb_config():
|
def build_mongodb_config():
|
||||||
|
"""
|
||||||
|
Build MongoDB configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: MongoDB configuration with connection string, database name, and TTL index seconds.
|
||||||
|
"""
|
||||||
username = getenv('MONGODB_USERNAME', 'root')
|
username = getenv('MONGODB_USERNAME', 'root')
|
||||||
password = getenv('MONGODB_PASSWORD', 'wKZDbMNU1c')
|
password = getenv('MONGODB_PASSWORD', 'wKZDbMNU1c')
|
||||||
uri = getenv('MONGODB_URL', 'localhost:27018')
|
uri = getenv('MONGODB_URL', 'localhost:27018')
|
||||||
@@ -24,6 +36,12 @@ def build_mongodb_config():
|
|||||||
|
|
||||||
|
|
||||||
def build_couchbase_config():
|
def build_couchbase_config():
|
||||||
|
"""
|
||||||
|
Build Couchbase configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Couchbase configuration with connection string, username, and password.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
'connection_string': getenv('COUCHBASE_CONNECTION_STRING', 'couchbase://localhost'),
|
'connection_string': getenv('COUCHBASE_CONNECTION_STRING', 'couchbase://localhost'),
|
||||||
'username': getenv('COUCHBASE_USERNAME', 'sientia'),
|
'username': getenv('COUCHBASE_USERNAME', 'sientia'),
|
||||||
@@ -32,6 +50,12 @@ def build_couchbase_config():
|
|||||||
|
|
||||||
|
|
||||||
def build_temporal_config():
|
def build_temporal_config():
|
||||||
|
"""
|
||||||
|
Build Temporal configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Temporal configuration with host and namespace settings.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
'temporal_host': getenv('TEMPORAL_HOST', 'localhost:7233'),
|
'temporal_host': getenv('TEMPORAL_HOST', 'localhost:7233'),
|
||||||
'temporal_namespace': getenv('TEMPORAL_NAMESPACE', 'default'),
|
'temporal_namespace': getenv('TEMPORAL_NAMESPACE', 'default'),
|
||||||
@@ -41,6 +65,12 @@ def build_temporal_config():
|
|||||||
|
|
||||||
|
|
||||||
def build_postgres_config():
|
def build_postgres_config():
|
||||||
|
"""
|
||||||
|
Build PostgreSQL configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: PostgreSQL configuration with connection details and connection pool settings.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
'host': getenv('POSTGRES_HOST', 'localhost'),
|
'host': getenv('POSTGRES_HOST', 'localhost'),
|
||||||
'port': int(getenv('POSTGRES_PORT', '5432')),
|
'port': int(getenv('POSTGRES_PORT', '5432')),
|
||||||
@@ -53,6 +83,12 @@ def build_postgres_config():
|
|||||||
|
|
||||||
|
|
||||||
def build_email_config():
|
def build_email_config():
|
||||||
|
"""
|
||||||
|
Build email configuration from environment variables.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Email configuration with SMTP server settings and sender credentials.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
'sender_email': getenv('EMAIL_SENDER', 'sientia-alerts@aignosi.com'),
|
'sender_email': getenv('EMAIL_SENDER', 'sientia-alerts@aignosi.com'),
|
||||||
'sender_password': getenv('EMAIL_SENDER_PASSWORD', 'sientia'),
|
'sender_password': getenv('EMAIL_SENDER_PASSWORD', 'sientia'),
|
||||||
|
|||||||
@@ -18,12 +18,33 @@ class EmailBuilder:
|
|||||||
self.general_template = file.read()
|
self.general_template = file.read()
|
||||||
|
|
||||||
def replace_parameters(self, template: str, parameters: dict) -> str:
|
def replace_parameters(self, template: str, parameters: dict) -> str:
|
||||||
|
"""
|
||||||
|
Replace parameters in a Jinja2 template with provided values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
template (str): The Jinja2 template string.
|
||||||
|
parameters (dict): Dictionary of parameters to replace in the template.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The rendered template with parameters replaced.
|
||||||
|
"""
|
||||||
# Criar um template Jinja2
|
# Criar um template Jinja2
|
||||||
template = Template(template)
|
template = Template(template)
|
||||||
|
|
||||||
return template.render(parameters)
|
return template.render(parameters)
|
||||||
|
|
||||||
def parameters(self, general_events: dict, mail_type: str) -> dict:
|
def parameters(self, general_events: dict, mail_type: str) -> dict:
|
||||||
|
"""
|
||||||
|
Build parameters dictionary for email templates based on general events and mail type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
general_events (dict): Dictionary containing events categorized by level (ERROR, WARNING, INFO).
|
||||||
|
Each level contains a 'models' key with model-specific event data.
|
||||||
|
mail_type (str): The type of email being sent.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Dictionary with mail_type and rendered event sections for each notification level.
|
||||||
|
"""
|
||||||
error_models = general_events.get('ERROR', {}).get('models', [])
|
error_models = general_events.get('ERROR', {}).get('models', [])
|
||||||
warning_models = general_events.get('WARNING', {}).get('models', [])
|
warning_models = general_events.get('WARNING', {}).get('models', [])
|
||||||
info_models = general_events.get('INFO', {}).get('models', [])
|
info_models = general_events.get('INFO', {}).get('models', [])
|
||||||
@@ -43,7 +64,16 @@ class EmailBuilder:
|
|||||||
|
|
||||||
def build_email(self, report_data: list[dict], mail_type: str) -> str:
|
def build_email(self, report_data: list[dict], mail_type: str) -> str:
|
||||||
"""
|
"""
|
||||||
Builds the email html.
|
Builds the email HTML by organizing report data by notification level and model.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
report_data (list[dict]): List of notification reports, each containing:
|
||||||
|
- level (str): Notification level (ERROR, WARNING, INFO)
|
||||||
|
- model_name (str): Name of the model
|
||||||
|
- Additional notification details
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Complete HTML email content ready for sending.
|
||||||
"""
|
"""
|
||||||
general_events = {}
|
general_events = {}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,21 @@ from typing import Any
|
|||||||
|
|
||||||
|
|
||||||
def common_config(config: dict[str, Any]):
|
def common_config(config: dict[str, Any]):
|
||||||
|
"""
|
||||||
|
Extract common configuration parameters from a pipeline configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict[str, Any]): Pipeline configuration containing:
|
||||||
|
- workflow_type (str): Type of workflow (e.g., 'scouter', 'predictions_batch')
|
||||||
|
- schedule_name (str): Name of the schedule
|
||||||
|
- frequency (str, optional): Frequency of execution (default: '1m')
|
||||||
|
- max_retry_policy (int, optional): Maximum retry attempts (default: 1)
|
||||||
|
- model_id (str): ID of the model
|
||||||
|
- models (dict): Model configuration containing 'name' field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Common configuration dictionary with extracted parameters.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
"workflow_type": config['workflow_type'],
|
"workflow_type": config['workflow_type'],
|
||||||
"schedule_name": config['schedule_name'],
|
"schedule_name": config['schedule_name'],
|
||||||
@@ -14,6 +29,18 @@ def common_config(config: dict[str, Any]):
|
|||||||
|
|
||||||
|
|
||||||
def minimal_retrain(config: dict[str, Any]):
|
def minimal_retrain(config: dict[str, Any]):
|
||||||
|
"""
|
||||||
|
Build minimal retrain configuration from pipeline config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict[str, Any]): Pipeline configuration containing:
|
||||||
|
- schedule_name (str): Name of the schedule
|
||||||
|
- query (str): SQL query for retraining
|
||||||
|
- Additional fields from common_config
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Minimal retrain configuration with workflow type set to 'minimal_retrain'.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
**common_config(config),
|
**common_config(config),
|
||||||
"workflow_type": "minimal_retrain",
|
"workflow_type": "minimal_retrain",
|
||||||
@@ -25,6 +52,25 @@ def minimal_retrain(config: dict[str, Any]):
|
|||||||
|
|
||||||
|
|
||||||
def scouter(config: dict[str, Any]):
|
def scouter(config: dict[str, Any]):
|
||||||
|
"""
|
||||||
|
Build scouter configuration from pipeline config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict[str, Any]): Pipeline configuration containing:
|
||||||
|
- filters (list[dict], optional): List of filter configurations
|
||||||
|
- read_tags (list[dict]): List of tag configurations with:
|
||||||
|
- filter_name (str): Name of the filter
|
||||||
|
- policy (str): Filter policy
|
||||||
|
- tag_name (str): Name of the tag
|
||||||
|
- aggr_func (str, optional): Aggregation function (default: 'lts')
|
||||||
|
- data_range (list[int], optional): Data range limits (default: [-100, 100])
|
||||||
|
- tag_retention_minutes (int, optional): Tag retention time in minutes (default: 60)
|
||||||
|
- debug_data_package (bool, optional): Enable debug data package (default: False)
|
||||||
|
- Additional fields from common_config
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Scouter configuration with topic, filters, tags, and retention settings.
|
||||||
|
"""
|
||||||
filters = {}
|
filters = {}
|
||||||
for f in config.get('filters', []):
|
for f in config.get('filters', []):
|
||||||
filters[f['filter_name']] = {
|
filters[f['filter_name']] = {
|
||||||
@@ -53,6 +99,19 @@ def scouter(config: dict[str, Any]):
|
|||||||
|
|
||||||
|
|
||||||
def overlap_filter_config(base_filter_config: dict[str, Any], config: list[dict[str, Any]]):
|
def overlap_filter_config(base_filter_config: dict[str, Any], config: list[dict[str, Any]]):
|
||||||
|
"""
|
||||||
|
Overlap filter configuration with base filter config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
base_filter_config (dict[str, Any]): Base filter configuration to extend.
|
||||||
|
config (list[dict[str, Any]]): List of filter configurations to add, each containing:
|
||||||
|
- filter_name (str): Name of the filter
|
||||||
|
- policy (str): Filter policy
|
||||||
|
- config (dict, optional): Additional filter configuration
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Extended filter configuration with new filters added.
|
||||||
|
"""
|
||||||
for fil in config:
|
for fil in config:
|
||||||
base_filter_config[fil['filter_name']] = {
|
base_filter_config[fil['filter_name']] = {
|
||||||
"policy": fil['policy'],
|
"policy": fil['policy'],
|
||||||
@@ -63,6 +122,15 @@ def overlap_filter_config(base_filter_config: dict[str, Any], config: list[dict[
|
|||||||
|
|
||||||
|
|
||||||
def process_path_priority(path_priority: list[str]):
|
def process_path_priority(path_priority: list[str]):
|
||||||
|
"""
|
||||||
|
Process and normalize path priority list to ensure it contains the required priorities.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path_priority (list[str]): List of path priorities to process.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: Normalized path priority list with exactly 3 elements: ["STOP", "CONTINUE", "REPEAT"].
|
||||||
|
"""
|
||||||
for priority in path_priority[:]:
|
for priority in path_priority[:]:
|
||||||
if priority not in ["STOP", "CONTINUE", "REPEAT"]:
|
if priority not in ["STOP", "CONTINUE", "REPEAT"]:
|
||||||
path_priority.remove(priority)
|
path_priority.remove(priority)
|
||||||
@@ -75,6 +143,26 @@ def process_path_priority(path_priority: list[str]):
|
|||||||
|
|
||||||
|
|
||||||
def predictions_batch(config: dict[str, Any]):
|
def predictions_batch(config: dict[str, Any]):
|
||||||
|
"""
|
||||||
|
Build predictions batch configuration from pipeline config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict[str, Any]): Pipeline configuration containing:
|
||||||
|
- write_tags (list[dict]): List of tag configurations with:
|
||||||
|
- server_id (str): ID of the OPC server
|
||||||
|
- type (str): Tag type ('prediction' or 'confidence')
|
||||||
|
- addr (str): Tag address
|
||||||
|
- data_type (str, optional): Data type (default: 'float')
|
||||||
|
- path_priority (list[str], optional): List of path priorities (default: ["STOP", "CONTINUE", "REPEAT"])
|
||||||
|
- input_filters (list[dict], optional): List of input filter configurations
|
||||||
|
- mlflow_transform_filters (list[dict], optional): List of MLflow transform filter configurations
|
||||||
|
- mlflow_predict_filters (list[dict], optional): List of MLflow predict filter configurations
|
||||||
|
- model_retention_minutes (int, optional): Model retention time in minutes (default: 60)
|
||||||
|
- Additional fields from common_config
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Predictions batch configuration with OPC output config, filters, and path priority.
|
||||||
|
"""
|
||||||
tags = {}
|
tags = {}
|
||||||
for tag in config.get('write_tags', []):
|
for tag in config.get('write_tags', []):
|
||||||
if tag['server_id'] not in tags:
|
if tag['server_id'] not in tags:
|
||||||
@@ -156,6 +244,23 @@ def gather_read_tags(pipelines: list[dict[str, Any]]) -> dict[str, Any]:
|
|||||||
|
|
||||||
def build_tag_config(tag: dict[str, Any], slot_config: dict[str, Any],
|
def build_tag_config(tag: dict[str, Any], slot_config: dict[str, Any],
|
||||||
opc_servers: dict[str, Any], i: int):
|
opc_servers: dict[str, Any], i: int):
|
||||||
|
"""
|
||||||
|
Build tag configuration for a specific slot and OPC server.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tag (dict[str, Any]): Tag configuration containing:
|
||||||
|
- server_id (str): ID of the OPC server
|
||||||
|
- tag_address (str): Address of the tag
|
||||||
|
slot_config (dict[str, Any]): Current slot configuration to update.
|
||||||
|
opc_servers (dict[str, Any]): Dictionary of OPC server configurations.
|
||||||
|
i (int): Slot number to configure.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: Updated slot configuration with the new tag.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the specified server_id is not found in opc_servers.
|
||||||
|
"""
|
||||||
server_id = tag['server_id']
|
server_id = tag['server_id']
|
||||||
|
|
||||||
if server_id not in opc_servers:
|
if server_id not in opc_servers:
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ POD_ID = os.getenv("POD_ID")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
"""
|
||||||
|
Main function to initialize and run the Temporal worker.
|
||||||
|
|
||||||
|
Sets up MongoDB connection, notification handler, Temporal client, and starts
|
||||||
|
multiple workers for different task queues (orchestrator, alerts, reports).
|
||||||
|
Handles graceful shutdown and error handling.
|
||||||
|
"""
|
||||||
host = os.getenv('TEMPORAL_HOST', 'localhost:7233')
|
host = os.getenv('TEMPORAL_HOST', 'localhost:7233')
|
||||||
namespace = os.getenv('TEMPORAL_NAMESPACE', 'default')
|
namespace = os.getenv('TEMPORAL_NAMESPACE', 'default')
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
@@ -176,6 +183,12 @@ async def main():
|
|||||||
|
|
||||||
|
|
||||||
def start_prometheus_server():
|
def start_prometheus_server():
|
||||||
|
"""
|
||||||
|
Start the Prometheus metrics server on the configured port.
|
||||||
|
|
||||||
|
Sets up HTTP server for metrics collection and marks the application as UP.
|
||||||
|
Exits the application if the server fails to start.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
port = int(os.getenv("HTTP_METRICS_PORT", 9090))
|
port = int(os.getenv("HTTP_METRICS_PORT", 9090))
|
||||||
start_http_server(port)
|
start_http_server(port)
|
||||||
|
|||||||
Reference in New Issue
Block a user