Skip to content

Commit 01453bd

Browse files
committed
new changes and optimizatoins
1 parent bb37ae4 commit 01453bd

17 files changed

+120
-338
lines changed

src/dt4acc/custom_tango/device_exporter_complete.py

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from typing import Dict, List, Optional
1111
from tango import Database, DbDevInfo, DevFailed
1212

13-
# Add src to path
1413
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
1514

1615
from dt4acc.core.utils.logger import get_logger
@@ -26,7 +25,7 @@ class CompleteDeviceExporter:
2625

2726
def __init__(self, timeout_seconds: int = 60, batch_size: int = 50):
2827
self.timeout_seconds = timeout_seconds
29-
self.batch_size = batch_size # Process devices in batches
28+
self.batch_size = batch_size
3029
self.exported_devices = []
3130
self.db = None
3231
self._init_database()
@@ -36,16 +35,14 @@ def _init_database(self):
3635
try:
3736
logger.info("🔗 Initializing database connection...")
3837
self.db = Database()
39-
# Test connection
4038
servers = self.db.get_server_list()
41-
logger.info(f"Database connected, found {len(servers)} servers")
39+
logger.info(f"Database connected, found {len(servers)} servers")
4240
except Exception as e:
43-
logger.error(f"Database connection failed: {e}")
41+
logger.error(f"Database connection failed: {e}")
4442
raise
4543

4644
def _format_device_name(self, name: str, device_type: str) -> str:
4745
"""Format device name according to Tango conventions."""
48-
# Clean the name and make it Tango-compatible
4946
clean_name = name.replace(" ", "_").replace("-", "_").upper()
5047
return f"{device_type}_{clean_name}"
5148

@@ -80,22 +77,21 @@ def db_worker():
8077
def _export_devices_in_batches(self, devices: List[str], device_type: str, device_class) -> int:
8178
"""Export devices in batches to avoid overwhelming the system."""
8279
if not devices:
83-
logger.warning(f"⚠️ No {device_type} devices found")
80+
logger.warning(f" No {device_type} devices found")
8481
return 0
8582

86-
logger.info(f"📊 Found {len(devices)} {device_type} devices")
87-
logger.info(f"🔄 Exporting in batches of {self.batch_size}...")
83+
logger.info(f" Found {len(devices)} {device_type} devices")
84+
logger.info(f"Exporting in batches of {self.batch_size}...")
8885

8986
exported_count = 0
9087
failed_count = 0
9188

92-
# Process devices in batches
9389
for i in range(0, len(devices), self.batch_size):
9490
batch = devices[i:i + self.batch_size]
9591
batch_num = (i // self.batch_size) + 1
9692
total_batches = (len(devices) + self.batch_size - 1) // self.batch_size
9793

98-
logger.info(f"📦 Processing batch {batch_num}/{total_batches} ({len(batch)} devices)...")
94+
logger.info(f"Processing batch {batch_num}/{total_batches} ({len(batch)} devices)...")
9995

10096
for device_name in batch:
10197
try:
@@ -109,35 +105,30 @@ def _export_devices_in_batches(self, devices: List[str], device_type: str, devic
109105
self.exported_devices.append(device_info.name)
110106
exported_count += 1
111107

112-
# Log progress every 10 devices
113108
if exported_count % 10 == 0:
114-
logger.info(f" Exported {exported_count} {device_type} devices so far...")
109+
logger.info(f" Exported {exported_count} {device_type} devices so far...")
115110

116111
except Exception as e:
117112
failed_count += 1
118-
logger.warning(f"⚠️ Failed to export {device_type} {device_name}: {e}")
113+
logger.warning(f" Failed to export {device_type} {device_name}: {e}")
119114
continue
120115

121-
# Small delay between batches to avoid overwhelming the system
122116
if i + self.batch_size < len(devices):
123117
time.sleep(0.1)
124118

125-
logger.info(f"Exported {exported_count} {device_type} devices")
119+
logger.info(f"Exported {exported_count} {device_type} devices")
126120
if failed_count > 0:
127-
logger.warning(f"⚠️ Failed to export {failed_count} {device_type} devices")
121+
logger.warning(f" Failed to export {failed_count} {device_type} devices")
128122

129123
return exported_count
130124

131125
def export_magnet_devices(self) -> int:
132126
"""Export ALL magnet devices with timeout protection."""
133127
try:
134-
logger.info("🔧 Exporting ALL magnet devices...")
135128

136-
# Get magnet data with timeout
137129
def get_magnet_data():
138130
from dt4acc.custom_epics.data.querries import get_magnets
139131
magnets = list(get_magnets())
140-
# Extract unique magnet names
141132
unique_magnets = list(set(magnet.get('name', '') for magnet in magnets if magnet.get('name')))
142133
return unique_magnets
143134

@@ -150,15 +141,14 @@ def get_magnet_data():
150141
return self._export_devices_in_batches(magnets, "MagnetDevice", MagnetDevice)
151142

152143
except Exception as e:
153-
logger.error(f"Magnet export failed: {e}")
144+
logger.error(f"Magnet export failed: {e}")
154145
return 0
155146

156147
def export_power_converter_devices(self) -> int:
157148
"""Export ALL power converter devices with timeout protection."""
158149
try:
159150
logger.info("🔧 Exporting ALL power converter devices...")
160151

161-
# Get power converter data with timeout
162152
def get_pc_data():
163153
from dt4acc.custom_epics.data.querries import get_unique_power_converters
164154
return get_unique_power_converters()
@@ -172,13 +162,13 @@ def get_pc_data():
172162
return self._export_devices_in_batches(power_converters, "PowerConverterDevice", PowerConverterDevice)
173163

174164
except Exception as e:
175-
logger.error(f" Power converter export failed: {e}")
165+
logger.error(f" Power converter export failed: {e}")
176166
return 0
177167

178168
def export_twiss_orbit_device(self) -> int:
179169
"""Export TwissOrbit device."""
180170
try:
181-
logger.info("🔧 Exporting TwissOrbit device...")
171+
logger.info("Exporting TwissOrbit device...")
182172

183173
device_info = DbDevInfo()
184174
device_info._class = TwissOrbitDevice.__name__
@@ -188,17 +178,17 @@ def export_twiss_orbit_device(self) -> int:
188178
self.db.add_device(device_info)
189179
self.exported_devices.append(device_info.name)
190180

191-
logger.info("Exported TwissOrbitDevice_MAIN")
181+
logger.info("Exported TwissOrbitDevice_MAIN")
192182
return 1
193183

194184
except Exception as e:
195-
logger.error(f"TwissOrbit device export failed: {e}")
185+
logger.error(f"TwissOrbit device export failed: {e}")
196186
return 0
197187

198188
def export_bpm_device(self) -> int:
199189
"""Export BPM device."""
200190
try:
201-
logger.info("🔧 Exporting BPM device...")
191+
logger.info(" Exporting BPM device...")
202192

203193
device_info = DbDevInfo()
204194
device_info._class = BPMDevice.__name__
@@ -208,16 +198,16 @@ def export_bpm_device(self) -> int:
208198
self.db.add_device(device_info)
209199
self.exported_devices.append(device_info.name)
210200

211-
logger.info(" Exported BPMDevice_MAIN")
201+
logger.info(" Exported BPMDevice_MAIN")
212202
return 1
213203

214204
except Exception as e:
215-
logger.error(f" BPM device export failed: {e}")
205+
logger.error(f" BPM device export failed: {e}")
216206
return 0
217207

218208
def export_all_devices(self) -> Dict[str, int]:
219209
"""Export ALL devices with comprehensive error handling."""
220-
logger.info("🚀 Starting COMPLETE device export...")
210+
logger.info("Starting COMPLETE device export...")
221211
start_time = time.time()
222212

223213
results = {
@@ -229,20 +219,14 @@ def export_all_devices(self) -> Dict[str, int]:
229219
}
230220

231221
try:
232-
# Export each device type with individual error handling
233-
logger.info("📦 Exporting ALL power converters...")
234222
results['power_converters'] = self.export_power_converter_devices()
235223

236-
logger.info("📦 Exporting ALL magnets...")
237224
results['magnets'] = self.export_magnet_devices()
238225

239-
logger.info("📦 Exporting TwissOrbit device...")
240226
results['twiss_orbit'] = self.export_twiss_orbit_device()
241227

242-
logger.info("📦 Exporting BPM device...")
243228
results['bpm'] = self.export_bpm_device()
244229

245-
# Calculate total
246230
results['total'] = sum([
247231
results['power_converters'],
248232
results['magnets'],
@@ -253,12 +237,10 @@ def export_all_devices(self) -> Dict[str, int]:
253237
end_time = time.time()
254238
duration = end_time - start_time
255239

256-
logger.info(f"✅ COMPLETE device export finished in {duration:.2f} seconds")
257-
logger.info(f"📊 TOTAL DEVICES EXPORTED: {results['total']}")
240+
258241
return results
259242

260243
except Exception as e:
261-
logger.error(f"❌ Complete device export failed: {e}")
262244
return results
263245

264246
def get_exported_devices(self) -> List[str]:

src/dt4acc/custom_tango/heartbeat_service.py

Lines changed: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import signal
1212
from datetime import datetime
1313

14-
# Add src to path (now we're in custom_tango folder)
1514
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
1615

1716
from dt4acc.core.utils.logger import get_logger
@@ -33,36 +32,27 @@ def __init__(self, interval_seconds: int = 1, log_interval: int = 10):
3332
def initialize_view(self):
3433
"""Initialize the view instance."""
3534
try:
36-
print("🔧 Initializing view for heartbeat service...")
37-
logger.info("🔧 Initializing view for heartbeat service...")
35+
logger.info("Initializing view for heartbeat service...")
3836

39-
# Set environment variable for Tango view
4037
os.environ["server"] = "tango"
4138

42-
# Get the view instance
4339
self.view = get_view_instance()
44-
print(f"✅ View initialized: {type(self.view).__name__}")
45-
logger.info(f"✅ View initialized: {type(self.view).__name__}")
40+
logger.info(f" View initialized: {type(self.view).__name__}")
4641

47-
# Test if view has heart_beat method
4842
if hasattr(self.view, 'heart_beat'):
49-
print(f"✅ View has heart_beat method")
50-
logger.info(f"✅ View has heart_beat method")
43+
logger.info(f"View has heart_beat method")
5144
return True
5245
else:
53-
print(f"❌ View does not have heart_beat method")
54-
logger.error(f"❌ View does not have heart_beat method")
46+
logger.error(f" View does not have heart_beat method")
5547
return False
5648

5749
except Exception as e:
58-
print(f"❌ Failed to initialize view: {e}")
59-
logger.error(f"❌ Failed to initialize view: {e}")
50+
logger.error(f"Failed to initialize view: {e}")
6051
return False
6152

6253
async def heartbeat_loop(self):
6354
"""Main heartbeat loop."""
64-
print("💓 Starting heartbeat loop...")
65-
logger.info("💓 Starting heartbeat loop...")
55+
logger.info("Starting heartbeat loop...")
6656

6757
self.start_time = datetime.now()
6858
self.iteration = 0
@@ -72,67 +62,50 @@ async def heartbeat_loop(self):
7262
await asyncio.sleep(self.interval_seconds)
7363
self.iteration += 1
7464

75-
# Call the heart_beat method to catch updates
7665
await self.view.heart_beat()
7766

78-
# Also check for any pending updates in the view
7967
if hasattr(self.view, 'monitor_updates'):
80-
# This will trigger any pending calculations
8168
pass
8269

83-
# Log progress every N iterations
8470
if self.iteration % self.log_interval == 0:
8571
elapsed = datetime.now() - self.start_time
86-
print(f"💓 Heartbeat iteration {self.iteration} (elapsed: {elapsed})")
87-
logger.info(f"💓 Heartbeat iteration {self.iteration} (elapsed: {elapsed})")
72+
logger.info(f"Heartbeat iteration {self.iteration} (elapsed: {elapsed})")
8873

8974
except asyncio.CancelledError:
90-
print("💓 Heartbeat loop was cancelled")
91-
logger.warning("💓 Heartbeat loop was cancelled")
75+
logger.warning("Heartbeat loop was cancelled")
9276
break
9377
except Exception as e:
94-
print(f"❌ Heartbeat error at iteration {self.iteration}: {e}")
95-
logger.error(f"❌ Heartbeat error at iteration {self.iteration}: {e}")
78+
logger.error(f"Heartbeat error at iteration {self.iteration}: {e}")
9679
# Continue running even if there's an error
9780
await asyncio.sleep(self.interval_seconds)
9881

99-
print("💓 Heartbeat loop stopped")
100-
logger.info("💓 Heartbeat loop stopped")
82+
logger.info("Heartbeat loop stopped")
10183

10284
def start(self):
10385
"""Start the heartbeat service."""
10486
if self.running:
105-
print("⚠️ Heartbeat service is already running")
10687
return False
10788

108-
print("🚀 Starting Heartbeat Service...")
109-
logger.info("🚀 Starting Heartbeat Service...")
89+
logger.info("Starting Heartbeat Service...")
11090

111-
# Initialize view
11291
if not self.initialize_view():
11392
print("❌ Failed to initialize view. Cannot start heartbeat.")
11493
return False
11594

116-
# Start the heartbeat loop
11795
self.running = True
11896

11997
try:
120-
# Create and run the event loop
12198
loop = asyncio.new_event_loop()
12299
asyncio.set_event_loop(loop)
123100

124-
print("💓 Heartbeat service started successfully!")
125-
logger.info("💓 Heartbeat service started successfully!")
101+
logger.info(" Heartbeat service started successfully!")
126102

127-
# Run the heartbeat loop
128103
loop.run_until_complete(self.heartbeat_loop())
129104

130105
except KeyboardInterrupt:
131-
print("\n⏹️ Heartbeat service interrupted by user")
132-
logger.info("💓 Heartbeat service interrupted by user")
106+
logger.info(" Heartbeat service interrupted by user")
133107
except Exception as e:
134-
print(f"❌ Heartbeat service error: {e}")
135-
logger.error(f"❌ Heartbeat service error: {e}")
108+
logger.error(f"Heartbeat service error: {e}")
136109
finally:
137110
self.stop()
138111
try:
@@ -145,22 +118,18 @@ def stop(self):
145118
if not self.running:
146119
return
147120

148-
print("🛑 Stopping Heartbeat Service...")
149-
logger.info("🛑 Stopping Heartbeat Service...")
121+
logger.info(" Stopping Heartbeat Service...")
150122

151123
self.running = False
152124

153125
if self.start_time:
154126
total_time = datetime.now() - self.start_time
155-
print(f"📊 Heartbeat service ran for {total_time} ({self.iteration} iterations)")
156-
logger.info(f"📊 Heartbeat service ran for {total_time} ({self.iteration} iterations)")
127+
logger.info(f"Heartbeat service ran for {total_time} ({self.iteration} iterations)")
157128

158-
print("✅ Heartbeat service stopped")
159-
logger.info("✅ Heartbeat service stopped")
129+
logger.info("Heartbeat service stopped")
160130

161131
def signal_handler(signum, frame):
162132
"""Handle interrupt signals."""
163-
print(f"\n📡 Received signal {signum}. Stopping heartbeat service...")
164133
if heartbeat_service:
165134
heartbeat_service.stop()
166135
sys.exit(0)
@@ -169,28 +138,22 @@ def main():
169138
"""Main entry point for heartbeat service."""
170139
global heartbeat_service
171140

172-
print("💓 Standalone Heartbeat Service")
173141
print("=" * 50)
174142
print("This service runs independently of the Tango server.")
175143
print("Make sure the Tango server is running before starting this service.")
176144
print("Press Ctrl+C to stop the service.")
177145
print("=" * 50)
178146

179-
# Register signal handlers
180147
signal.signal(signal.SIGINT, signal_handler)
181148
signal.signal(signal.SIGTERM, signal_handler)
182149

183-
# Create heartbeat service
184150
heartbeat_service = HeartbeatService(interval_seconds=1, log_interval=10)
185151

186152
try:
187-
# Start the service
188153
heartbeat_service.start()
189154
except KeyboardInterrupt:
190-
print("\n⏹️ Service stopped by user")
191155
except Exception as e:
192-
print(f"❌ Service failed: {e}")
193-
logger.error(f"❌ Service failed: {e}")
156+
logger.error(f" Service failed: {e}")
194157

195158
if __name__ == "__main__":
196159
heartbeat_service = None

0 commit comments

Comments
 (0)