mirror of
https://gitee.com/quecpython/helios-service.git
synced 2025-05-19 06:08:22 +08:00
204 lines
5.7 KiB
Python
204 lines
5.7 KiB
Python
from usr.bin.components.blinker_min import Signal, signal
|
|
from event_message import Event, EventManager, EventMessageObject
|
|
from usr.bin.components.service_models import QMessageModel, LockMsgModel
|
|
import _thread
|
|
|
|
ANY = "anonymous"
|
|
|
|
|
|
class AbstractService(object):
|
|
def __init__(self, sign):
|
|
self.__name = sign
|
|
|
|
self.__signal = signal(sign)
|
|
|
|
self.__event = Event(sign)
|
|
|
|
self.__em = EventManager()
|
|
|
|
self.__message_id = 0
|
|
|
|
self.__service_status = 0
|
|
|
|
self.__em.register_event(self.__event)
|
|
|
|
self.__mode = 1
|
|
|
|
def set_mode(self, mode):
|
|
self.__mode = mode
|
|
|
|
@property
|
|
def mode(self):
|
|
return self.__mode
|
|
|
|
@property
|
|
def name(self):
|
|
return self.__name
|
|
|
|
@property
|
|
def message_id(self):
|
|
"""return self.next message id."""
|
|
return self.__message_id + 1
|
|
|
|
@property
|
|
def signal(self):
|
|
"""signal to get by this method"""
|
|
return self.__signal
|
|
|
|
def ms_id_increase(self):
|
|
if self.__message_id > 99999:
|
|
self.__message_id = 0
|
|
else:
|
|
self.__message_id += 1
|
|
return self.message_id
|
|
|
|
def _get_message(self, sender=None, msg_type=0xFF, message=None, callback=None, lock_msg=None):
|
|
"""get message"""
|
|
if callback is not None and not callable(callback):
|
|
return None
|
|
ms_id = self.ms_id_increase()
|
|
qm = QMessageModel(ms_id=ms_id, msg_type=msg_type, message=message, sender=sender, from_event=self.__event.name,
|
|
lock_msg=lock_msg)
|
|
return qm
|
|
|
|
def _callback(self, **kwargs):
|
|
"""event callback"""
|
|
em = kwargs.get("event_message", False)
|
|
if em.msg:
|
|
msg = em.msg
|
|
try:
|
|
self.signal.send(em.msg.sender, message=msg())
|
|
except Exception as e:
|
|
success = 0
|
|
else:
|
|
success = 1
|
|
resp_data = dict(message=msg(), success=success)
|
|
if em.callback is not None:
|
|
try:
|
|
em.callback(**resp_data)
|
|
except Exception as e:
|
|
pass
|
|
if msg.lock_msg is not None:
|
|
msg.lock_msg.msg = resp_data
|
|
msg.lock_msg.lock.release()
|
|
|
|
def _clear(self, *args, **kwargs):
|
|
""" stop crontab task"""
|
|
self.__event.clear()
|
|
|
|
def _add_default_handler(self):
|
|
"""add default handler"""
|
|
self.add_handler(self._callback)
|
|
|
|
def register_event(self):
|
|
"""achieve by class extend AbstractService"""
|
|
pass
|
|
|
|
def prepare_before_start(self):
|
|
"""prepare before start action"""
|
|
pass
|
|
|
|
def prepare_before_stop(self):
|
|
"""prepare after start action"""
|
|
pass
|
|
|
|
def start_crontab(self, *args, **kwargs):
|
|
"""achieve by timer task"""
|
|
pass
|
|
|
|
def add_handler(self, handler):
|
|
"""
|
|
support for scan addition and manual sword
|
|
:param handler: deal handler
|
|
:return:
|
|
"""
|
|
self.__event.add_handler(handler)
|
|
return handler
|
|
|
|
def add_handler_via(self):
|
|
"""
|
|
Support for multiple annotations
|
|
:return:
|
|
"""
|
|
|
|
def decorator(fn):
|
|
self.add_handler(fn)
|
|
return fn
|
|
|
|
return decorator
|
|
|
|
def send_msg_async(self, msg_type=0xFF, message=None, callback=None, sender=None):
|
|
if self.status():
|
|
qm = self._get_message(sender=sender, msg_type=msg_type, message=message, callback=callback)
|
|
self.__event.post(qm, callback=callback)
|
|
else:
|
|
return 0
|
|
|
|
def send_msg_sync(self, msg_type=0xFF, message=None, callback=None, sender=None):
|
|
if self.status():
|
|
lock = _thread.allocate_lock()
|
|
lock_msg = LockMsgModel(lock)
|
|
qm = self._get_message(sender=sender, msg_type=msg_type, message=message, callback=callback,
|
|
lock_msg=lock_msg)
|
|
self.__event.post(qm, callback=callback)
|
|
lock_msg.lock.acquire()
|
|
msg = lock_msg.msg
|
|
del lock_msg
|
|
return msg
|
|
else:
|
|
return 0
|
|
|
|
def send_msg(self, msg_type=0xFF, message=None, callback=None, sender=None, mode=None):
|
|
mode_pattern = self.mode
|
|
if mode is not None:
|
|
mode_pattern = mode
|
|
if mode_pattern:
|
|
return self.send_msg_async(msg_type=msg_type, message=message, callback=callback, sender=sender)
|
|
else:
|
|
return self.send_msg_sync(msg_type=msg_type, message=message, callback=callback, sender=sender)
|
|
|
|
def _component_start(self):
|
|
"""start components"""
|
|
if not self.__service_status:
|
|
self.register_event()
|
|
self._add_default_handler()
|
|
self.prepare_before_start()
|
|
self.start_crontab()
|
|
|
|
def start(self):
|
|
"""
|
|
start the service
|
|
:return: 1 or 0
|
|
"""
|
|
self._component_start()
|
|
self.__service_status = self.__em.start()
|
|
return self.__service_status
|
|
|
|
def status(self):
|
|
"""
|
|
status of service
|
|
:return:
|
|
"""
|
|
return self.__em.status
|
|
|
|
def stop(self):
|
|
"""
|
|
stop the service
|
|
:return:
|
|
"""
|
|
self.prepare_before_stop()
|
|
self.__service_status = self.__em.stop()
|
|
return self.__service_status
|
|
|
|
def close(self):
|
|
self._clear()
|
|
|
|
def subscribe(self, cb, sender=ANY):
|
|
self.signal.connect(cb, sender=sender)
|
|
|
|
def unsubscribe(self, cb, sender=ANY):
|
|
self.signal.disconnect(cb, sender=sender)
|
|
|
|
def publish(self, msg, sender=ANY, msg_type=0XFF):
|
|
self.send_msg(message=msg, msg_type=msg_type, sender=sender)
|