#!/usr/bin/env python # -*- coding: utf-8 -*- """ 脚本注册中心数据模型 记录脚本实例的运行状态和注册信息 """ from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, ForeignKey, JSON from sqlalchemy.sql import func from sqlalchemy.orm import relationship from .base import Base class VWEDScriptRegistry(Base): """脚本注册中心模型""" __tablename__ = 'vwed_script_registry' id = Column(Integer, primary_key=True, autoincrement=True, comment='注册记录ID') script_id = Column(String(255), nullable=False, unique=True, comment='脚本实例ID') file_id = Column(Integer, ForeignKey('vwed_script_file.id'), nullable=False, comment='脚本文件ID') script_path = Column(String(500), nullable=False, comment='脚本相对路径') status = Column(String(20), nullable=False, default='starting', comment='运行状态: starting, running, stopping, stopped, error') process_id = Column(String(50), comment='进程ID') host_info = Column(JSON, comment='主机信息') start_params = Column(JSON, comment='启动参数') resource_limits = Column(JSON, comment='资源限制配置') performance_stats = Column(JSON, comment='性能统计信息') error_message = Column(Text, comment='错误信息') api_count = Column(Integer, default=0, comment='注册的API数量') function_count = Column(Integer, default=0, comment='注册的函数数量') event_count = Column(Integer, default=0, comment='注册的事件监听器数量') timer_count = Column(Integer, default=0, comment='注册的定时任务数量') last_heartbeat = Column(DateTime, comment='最后心跳时间') started_at = Column(DateTime, nullable=False, default=func.now(), comment='启动时间') stopped_at = Column(DateTime, comment='停止时间') created_at = Column(DateTime, nullable=False, default=func.now(), comment='创建时间') updated_at = Column(DateTime, nullable=False, default=func.now(), onupdate=func.now(), comment='更新时间') # 关联关系 script_file = relationship("VWEDScriptFile", backref="registry_records") def __repr__(self): return f"" def to_dict(self): """转换为字典格式""" return { 'id': self.id, 'script_id': self.script_id, 'file_id': self.file_id, 'script_path': self.script_path, 'status': self.status, 'process_id': self.process_id, 'host_info': self.host_info, 'start_params': self.start_params, 'resource_limits': self.resource_limits, 'performance_stats': self.performance_stats, 'error_message': self.error_message, 'registrations': { 'apis': self.api_count, 'functions': self.function_count, 'events': self.event_count, 'timers': self.timer_count }, 'last_heartbeat': self.last_heartbeat.isoformat() if self.last_heartbeat else None, 'started_at': self.started_at.isoformat() if self.started_at else None, 'stopped_at': self.stopped_at.isoformat() if self.stopped_at else None, 'created_at': self.created_at.isoformat() if self.created_at else None, 'updated_at': self.updated_at.isoformat() if self.updated_at else None, } @property def uptime_seconds(self): """计算运行时长(秒)""" if not self.started_at: return 0 import datetime end_time = self.stopped_at or datetime.datetime.now() delta = end_time - self.started_at return int(delta.total_seconds()) @property def is_running(self): """判断是否正在运行""" return self.status in ['starting', 'running'] def update_heartbeat(self): """更新心跳时间""" import datetime self.last_heartbeat = datetime.datetime.now() def update_registration_counts(self, apis=0, functions=0, events=0, timers=0): """更新注册统计""" self.api_count = apis self.function_count = functions self.event_count = events self.timer_count = timers def mark_stopped(self, error_message=None): """标记为已停止""" import datetime self.status = 'error' if error_message else 'stopped' self.stopped_at = datetime.datetime.now() if error_message: self.error_message = error_message