VWED_server/data/models/script_registry.py

108 lines
4.6 KiB
Python
Raw Normal View History

2025-09-12 16:15:13 +08:00
#!/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"<VWEDScriptRegistry(id={self.id}, script_id='{self.script_id}', status='{self.status}')>"
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