1010"""
1111
1212import sys
13+ import os
14+ import time
1315import json
1416from datetime import datetime
1517
1618from swf_common_lib .base_agent import BaseAgent , setup_environment
17- import fastmon_utils as fastmon_utils
19+ from swf_fastmon_agent import fastmon_utils
1820
1921
2022class FastMonitorAgent (BaseAgent ):
@@ -42,6 +44,9 @@ def __init__(self, config: dict, debug=False):
4244
4345 self .logger .info ("Fast Monitor Agent initialized successfully" )
4446
47+ # Set destination for broadcasting TF file notifications
48+ self .destination = os .getenv ('ACTIVEMQ_FASTMON_TOPIC' , 'epictopic' )
49+
4550 self .config = config
4651
4752 # Validate configuration
@@ -51,7 +56,12 @@ def __init__(self, config: dict, debug=False):
5156 # Fast monitoring specific state
5257 self .stf_messages_processed = 0
5358 self .last_message_time = None
54- self .processing_stats = {'total_stf_messages' : 0 , 'total_tf_files_created' : 0 }
59+ self .files_processed = 0 # For continuous monitoring mode
60+ self .processing_stats = {
61+ 'total_stf_messages' : 0 ,
62+ 'total_tf_files_created' : 0 ,
63+ 'total_files' : 0 # For continuous monitoring mode
64+ }
5565
5666
5767 def _emulate_stf_registration_and_sampling (self ):
@@ -88,20 +98,27 @@ def _emulate_stf_registration_and_sampling(self):
8898 stf_file = fastmon_utils .record_stf_file (file_path , self .config , self , self .logger )
8999 self .files_processed += 1
90100
91- # Simulate TF subsamples for this STF file
92- tf_subsamples = fastmon_utils .simulate_tf_subsamples (stf_file , file_path , self .config , self .logger )
93-
94- # Record each TF file in the FastMonFile table
95- tf_files_created = 0
96- for tf_metadata in tf_subsamples :
97- tf_file = fastmon_utils .record_tf_file (stf_file , tf_metadata , self .config , self , self .logger )
98- if tf_file :
99- tf_files_created += 1
100- # Send notification to clients about new TF file
101- self .send_tf_file_notification (tf_file , stf_file )
102- tf_files_registered .append (tf_file )
101+ # Create mock stf_ready message (matching format from data agent)
102+ message_data = {
103+ "msg_type" : "stf_ready" ,
104+ "filename" : stf_file .get ('stf_filename' ),
105+ "file_id" : stf_file .get ('file_id' ), # UUID for foreign key
106+ "run_id" : stf_file .get ('run' ),
107+ "file_url" : stf_file .get ('metadata' , {}).get ('file_url' , '' ),
108+ "checksum" : stf_file .get ('checksum' , '' ),
109+ "size_bytes" : stf_file .get ('file_size_bytes' ),
110+ "start" : stf_file .get ('metadata' , {}).get ('creation_time' , '' ),
111+ "end" : stf_file .get ('metadata' , {}).get ('modification_time' , '' ),
112+ "state" : "physics" ,
113+ "substate" : "running" ,
114+ "processed_by" : self .agent_name
115+ }
116+
117+ # Use the same sample_timeframes method as message-driven mode
118+ tf_files = self .sample_timeframes (message_data )
119+ tf_files_registered .extend (tf_files )
103120
104- self .logger .info (f"Registered { tf_files_created } TF subsamples for STF file { stf_file ['filename ' ]} " )
121+ self .logger .info (f"Processed STF file { stf_file ['stf_filename ' ]} -> { len ( tf_files ) } TF files " )
105122
106123 # Report successful processing
107124 self .report_agent_status ('OK' , f'Emulating { len (tf_files_registered )} fast monitoring files' )
@@ -173,22 +190,68 @@ def sample_timeframes(self, message_data):
173190 self .logger .error ("No filename provided in message" )
174191 return tf_files_registered
175192
193+ # Track workflow stage (optional - controlled by FASTMON_TRACK_WORKFLOW env var)
194+ workflow_id = message_data .get ('workflow_id' )
195+ stage_id = None
196+ track_workflow = os .getenv ('FASTMON_TRACK_WORKFLOW' , 'false' ).lower () == 'true'
197+
198+ if workflow_id and track_workflow :
199+ try :
200+ # Create workflow stage entry for fast monitoring
201+ stage_data = {
202+ 'workflow' : workflow_id ,
203+ 'agent_name' : self .agent_name ,
204+ 'agent_type' : 'fastmon' ,
205+ 'status' : 'fastmon_received' ,
206+ 'input_message' : message_data
207+ }
208+ stage = self .call_monitor_api ('POST' , '/workflow-stages/' , stage_data )
209+ stage_id = stage .get ('id' )
210+ self .logger .debug (f"Created workflow stage { stage_id } for workflow { workflow_id } " )
211+
212+ # Update to processing status
213+ self .call_monitor_api ('PATCH' , f'/workflow-stages/{ stage_id } /' , {
214+ 'status' : 'fastmon_processing' ,
215+ 'started_at' : datetime .now ().isoformat ()
216+ })
217+ except Exception as e :
218+ self .logger .warning (f"Could not create workflow stage: { e } " )
219+
220+ # Simulate TF subsamples from STF data
176221 tf_subsamples = fastmon_utils .simulate_tf_subsamples (message_data , self .config , self .logger , self .agent_name )
177222
178- # Record each TF file in the FastMonFile table
223+ # Record each TF file in the FastMonFile table and send notifications
179224 # TODO: register in bulk
180225 tf_files_created = 0
181226 for tf_metadata in tf_subsamples :
182227 self .logger .debug (f"Processing { tf_metadata } " )
183228 tf_file = fastmon_utils .record_tf_file (tf_metadata , self .config , self , self .logger )
184229 if tf_file :
185230 tf_files_created += 1
231+ # Send notification to clients about new TF file
232+ self .send_tf_file_notification (tf_file , message_data )
186233 tf_files_registered .append (tf_file )
187234
188235 # Update TF creation stats
189236 self .processing_stats ['total_tf_files_created' ] += tf_files_created
190237
191238 self .logger .info (f"Registered { tf_files_created } TF subsamples for STF file { message_data .get ('filename' )} " )
239+
240+ # Mark workflow stage as complete
241+ if stage_id :
242+ try :
243+ output_message = {
244+ 'tf_files_created' : tf_files_created ,
245+ 'tf_filenames' : [tf .get ('tf_filename' ) for tf in tf_files_registered if tf ]
246+ }
247+ self .call_monitor_api ('PATCH' , f'/workflow-stages/{ stage_id } /' , {
248+ 'status' : 'fastmon_complete' ,
249+ 'completed_at' : datetime .now ().isoformat (),
250+ 'output_message' : output_message
251+ })
252+ except Exception as e :
253+ self .logger .warning (f"Could not update workflow stage: { e } " )
254+
192255 return tf_files_registered
193256
194257 def start_continuous_monitoring (self ):
0 commit comments