mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-22 06:58:17 +01:00
Event Bus cleanup added
This commit is contained in:
parent
35ee2fbad9
commit
e2d4485f1f
11 changed files with 516 additions and 664 deletions
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@ from core.api import request_mapping, on_event
|
||||||
from core.controller.crud_controller import CRUDController
|
from core.controller.crud_controller import CRUDController
|
||||||
from core.database.model import KettleModel
|
from core.database.model import KettleModel
|
||||||
from core.http_endpoints.http_api import HttpAPI
|
from core.http_endpoints.http_api import HttpAPI
|
||||||
|
from core.job.aiohttp import get_scheduler_from_app
|
||||||
from core.utils import json_dumps
|
from core.utils import json_dumps
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +73,15 @@ class KettleController(CRUDController):
|
||||||
self.cbpi.bus.fire(topic="kettle/%s/automatic" % id, id=id)
|
self.cbpi.bus.fire(topic="kettle/%s/automatic" % id, id=id)
|
||||||
return (True, "Logic switched on switched")
|
return (True, "Logic switched on switched")
|
||||||
|
|
||||||
|
@on_event(topic="job/done")
|
||||||
|
def job_stop(self, key, **kwargs) -> None:
|
||||||
|
|
||||||
|
name = key.split("_")
|
||||||
|
kettle = self.cache[int(name[2])]
|
||||||
|
kettle.instance = None
|
||||||
|
|
||||||
|
print("STOP KETTLE LOGIC", int(name[2]))
|
||||||
|
|
||||||
@on_event(topic="kettle/+/automatic")
|
@on_event(topic="kettle/+/automatic")
|
||||||
async def handle_automtic_event(self, id, **kwargs):
|
async def handle_automtic_event(self, id, **kwargs):
|
||||||
|
|
||||||
|
@ -90,7 +100,7 @@ class KettleController(CRUDController):
|
||||||
|
|
||||||
if hasattr(kettle, "instance") is False:
|
if hasattr(kettle, "instance") is False:
|
||||||
kettle.instance = None
|
kettle.instance = None
|
||||||
|
self._is_logic_running(id)
|
||||||
if kettle.instance is None:
|
if kettle.instance is None:
|
||||||
if kettle.logic in self.types:
|
if kettle.logic in self.types:
|
||||||
clazz = self.types.get("CustomKettleLogic")["class"]
|
clazz = self.types.get("CustomKettleLogic")["class"]
|
||||||
|
@ -98,13 +108,15 @@ class KettleController(CRUDController):
|
||||||
cfg.update(dict(cbpi=self.cbpi))
|
cfg.update(dict(cbpi=self.cbpi))
|
||||||
kettle.instance = clazz(**cfg)
|
kettle.instance = clazz(**cfg)
|
||||||
print("START LOGIC")
|
print("START LOGIC")
|
||||||
await self.cbpi.start_job(kettle.instance.run(), "Kettle_logic_%s" % kettle.id, "kettle_logic")
|
await self.cbpi.start_job(kettle.instance.run(), "Kettle_logic_%s" % kettle.id, "kettle_logic%s"%id)
|
||||||
else:
|
else:
|
||||||
kettle.instance.running = False
|
kettle.instance.running = False
|
||||||
kettle.instance = None
|
kettle.instance = None
|
||||||
|
|
||||||
|
|
||||||
|
def _is_logic_running(self, kettle_id):
|
||||||
|
scheduler = get_scheduler_from_app(self.cbpi.app)
|
||||||
|
print("JOB KETTLE RUNNING", scheduler.is_running("Kettle_logic_%s"%kettle_id))
|
||||||
|
|
||||||
async def heater_on(self, id):
|
async def heater_on(self, id):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -35,4 +35,8 @@ class SystemController():
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
# await j.close()
|
# await j.close()
|
||||||
return web.json_response(data=result)
|
return web.json_response(data=result)
|
||||||
|
|
||||||
|
@request_mapping("/events", method="GET", name="get_all_events", auth_required=False)
|
||||||
|
def get_all_events(self, request):
|
||||||
|
return web.json_response(data=self.cbpi.bus.dump())
|
|
@ -49,8 +49,8 @@ class CraftBeerPi():
|
||||||
self.app = web.Application(middlewares=middlewares)
|
self.app = web.Application(middlewares=middlewares)
|
||||||
self.initializer = []
|
self.initializer = []
|
||||||
|
|
||||||
setup(self.app)
|
setup(self.app, self)
|
||||||
self.bus = EventBus(self)
|
self.bus = EventBus(self.app.loop)
|
||||||
self.ws = WebSocket(self)
|
self.ws = WebSocket(self)
|
||||||
self.actor = ActorController(self)
|
self.actor = ActorController(self)
|
||||||
self.sensor = SensorController(self)
|
self.sensor = SensorController(self)
|
||||||
|
@ -232,6 +232,8 @@ class CraftBeerPi():
|
||||||
await self.sensor.init()
|
await self.sensor.init()
|
||||||
await self.actor.init()
|
await self.actor.init()
|
||||||
await self.kettle.init()
|
await self.kettle.init()
|
||||||
|
import pprint
|
||||||
|
pprint.pprint(self.bus.dump())
|
||||||
|
|
||||||
async def load_plugins(app):
|
async def load_plugins(app):
|
||||||
#await PluginController.load_plugin_list()
|
#await PluginController.load_plugin_list()
|
||||||
|
|
101
core/eventbus.py
101
core/eventbus.py
|
@ -1,14 +1,9 @@
|
||||||
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
|
|
||||||
class EventBus(object):
|
class EventBus(object):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
__slots__ = '_children', '_content'
|
__slots__ = '_children', '_content'
|
||||||
|
|
||||||
|
@ -16,11 +11,8 @@ class EventBus(object):
|
||||||
self._children = {}
|
self._children = {}
|
||||||
self._content = None
|
self._content = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Content(object):
|
class Content(object):
|
||||||
def __init__(self, parent, topic, method, once):
|
def __init__(self, parent, topic, method, once):
|
||||||
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.method = method
|
self.method = method
|
||||||
self.name = method.__name__
|
self.name = method.__name__
|
||||||
|
@ -28,11 +20,10 @@ class EventBus(object):
|
||||||
self.topic = topic
|
self.topic = topic
|
||||||
|
|
||||||
def register(self, topic, method, once=False):
|
def register(self, topic, method, once=False):
|
||||||
print("REGISTER", topic, method)
|
|
||||||
if method in self.registry:
|
if method in self.registry:
|
||||||
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
||||||
self.logger.info("Topic %s", topic)
|
self.logger.info("Topic %s", topic)
|
||||||
|
|
||||||
node = self._root
|
node = self._root
|
||||||
for sym in topic.split('/'):
|
for sym in topic.split('/'):
|
||||||
node = node._children.setdefault(sym, self.Node())
|
node = node._children.setdefault(sym, self.Node())
|
||||||
|
@ -40,16 +31,10 @@ class EventBus(object):
|
||||||
if not isinstance(node._content, list):
|
if not isinstance(node._content, list):
|
||||||
node._content = []
|
node._content = []
|
||||||
|
|
||||||
|
|
||||||
c = self.Content(node, topic, method, once)
|
c = self.Content(node, topic, method, once)
|
||||||
|
|
||||||
|
|
||||||
node._content.append(c)
|
node._content.append(c)
|
||||||
print(c, node._content, topic)
|
|
||||||
self.registry[method] = c
|
self.registry[method] = c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_callbacks(self, key):
|
def get_callbacks(self, key):
|
||||||
try:
|
try:
|
||||||
node = self._root
|
node = self._root
|
||||||
|
@ -61,7 +46,6 @@ class EventBus(object):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise KeyError(key)
|
raise KeyError(key)
|
||||||
|
|
||||||
|
|
||||||
def unregister(self, method):
|
def unregister(self, method):
|
||||||
self.logger.info("Unregister %s", method.__name__)
|
self.logger.info("Unregister %s", method.__name__)
|
||||||
if method in self.registry:
|
if method in self.registry:
|
||||||
|
@ -74,58 +58,67 @@ class EventBus(object):
|
||||||
if clean_idx is not None:
|
if clean_idx is not None:
|
||||||
del content.parent._content[clean_idx]
|
del content.parent._content[clean_idx]
|
||||||
|
|
||||||
'''
|
def __init__(self, loop):
|
||||||
def unregister(self, key, method):
|
|
||||||
lst = []
|
|
||||||
try:
|
|
||||||
parent, node = None, self._root
|
|
||||||
for k in key.split('/'):
|
|
||||||
parent, node = node, node._children[k]
|
|
||||||
lst.append((parent, k, node))
|
|
||||||
except KeyError:
|
|
||||||
raise KeyError(key)
|
|
||||||
else: # cleanup
|
|
||||||
for parent, k, node in reversed(lst):
|
|
||||||
if node._children or node._content is not None:
|
|
||||||
break
|
|
||||||
del parent._children[k]
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, cbpi):
|
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self._root = self.Node()
|
self._root = self.Node()
|
||||||
self.registry = {}
|
self.registry = {}
|
||||||
self.docs = {}
|
self.docs = {}
|
||||||
self.cbpi = cbpi
|
if loop is not None:
|
||||||
|
self.loop = loop
|
||||||
|
else:
|
||||||
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
print(self.loop)
|
||||||
|
|
||||||
def fire(self, topic: str, **kwargs) -> None:
|
def fire(self, topic: str, **kwargs) -> None:
|
||||||
print("#### FIRE", topic)
|
|
||||||
self.logger.info("EMIT EVENT %s", topic)
|
self.logger.info("EMIT EVENT %s", topic)
|
||||||
|
|
||||||
cleanup_methods = []
|
trx = dict(i=0)
|
||||||
for content_array in self.iter_match(topic):
|
for e in self.iter_match(topic):
|
||||||
|
content_array = e
|
||||||
print(content_array)
|
keep_idx = []
|
||||||
cleanup = []
|
|
||||||
for idx, content_obj in enumerate(content_array):
|
for idx, content_obj in enumerate(content_array):
|
||||||
print("#################")
|
|
||||||
|
|
||||||
print("TOPIC", content_obj.method, content_obj.topic)
|
|
||||||
print("#################")
|
|
||||||
if inspect.iscoroutinefunction(content_obj.method):
|
if inspect.iscoroutinefunction(content_obj.method):
|
||||||
self.cbpi.app.loop.create_task(content_obj.method(**kwargs, topic = topic))
|
if hasattr(content_obj.method, "future"):
|
||||||
|
|
||||||
|
self.loop.create_task(content_obj.method(**kwargs, future=content_obj.method.future, topic=topic))
|
||||||
|
else:
|
||||||
|
self.loop.create_task(content_obj.method(**kwargs, topic = topic))
|
||||||
else:
|
else:
|
||||||
content_obj.method(**kwargs, topic = topic)
|
if hasattr(content_obj.method, "future"):
|
||||||
|
content_obj.method(**kwargs, future=content_obj.method.future, topic=topic)
|
||||||
|
else:
|
||||||
|
content_obj.method(**kwargs, topic = topic)
|
||||||
|
|
||||||
if content_obj.once is True:
|
#if inspect.iscoroutinefunction(content_obj.method):
|
||||||
cleanup.append(idx)
|
# self.loop.create_task(content_obj.method(**kwargs, trx=trx, topic=topic))
|
||||||
for idx in cleanup:
|
#else:
|
||||||
del content_array[idx]
|
# content_obj.method(**kwargs, trx=trx, topic=topic)
|
||||||
|
if content_obj.once is False:
|
||||||
|
keep_idx.append(idx)
|
||||||
|
|
||||||
|
# FILTER only elements with are required
|
||||||
|
if len(keep_idx) < len(e):
|
||||||
|
e[0].parent._content = [e[0].parent._content[i] for i in keep_idx]
|
||||||
|
|
||||||
print(self._root)
|
print("DONE", trx)
|
||||||
print("#### FIRE END ######")
|
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
def rec(node, i=0):
|
||||||
|
result = []
|
||||||
|
if node._content is not None:
|
||||||
|
for c in node._content:
|
||||||
|
result.append(dict(topic=c.topic, method=c.method.__name__, path=c.method.__module__, once=c.once))
|
||||||
|
|
||||||
|
if node._children is not None:
|
||||||
|
for c in node._children:
|
||||||
|
result = result + rec(node._children[c], i + 1)
|
||||||
|
return result
|
||||||
|
|
||||||
|
result = rec(self._root)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def iter_match(self, topic):
|
def iter_match(self, topic):
|
||||||
|
|
||||||
|
|
132
core/eventbus3.py
Normal file
132
core/eventbus3.py
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import inspect
|
||||||
|
import logging
|
||||||
|
|
||||||
|
class EventBus(object):
|
||||||
|
|
||||||
|
def __init__(self, cbpi):
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
|
self._root = self.Node()
|
||||||
|
self.registry = {}
|
||||||
|
self.docs = {}
|
||||||
|
self.cbpi = cbpi
|
||||||
|
|
||||||
|
class Node(object):
|
||||||
|
__slots__ = '_children', '_content'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._children = {}
|
||||||
|
self._content = None
|
||||||
|
|
||||||
|
|
||||||
|
class Content(object):
|
||||||
|
def __init__(self, parent, topic, method, once):
|
||||||
|
|
||||||
|
self.parent = parent
|
||||||
|
self.method = method
|
||||||
|
self.name = method.__name__
|
||||||
|
self.once = once
|
||||||
|
self.topic = topic
|
||||||
|
|
||||||
|
def register(self, topic, method, once=False):
|
||||||
|
print("REGISTER", topic, method)
|
||||||
|
if method in self.registry:
|
||||||
|
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
||||||
|
self.logger.info("Topic %s", topic)
|
||||||
|
|
||||||
|
node = self._root
|
||||||
|
for sym in topic.split('/'):
|
||||||
|
node = node._children.setdefault(sym, self.Node())
|
||||||
|
|
||||||
|
if not isinstance(node._content, list):
|
||||||
|
node._content = []
|
||||||
|
|
||||||
|
|
||||||
|
c = self.Content(node, topic, method, once)
|
||||||
|
|
||||||
|
|
||||||
|
node._content.append(c)
|
||||||
|
print(c, node._content, topic)
|
||||||
|
self.registry[method] = c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_callbacks(self, key):
|
||||||
|
try:
|
||||||
|
node = self._root
|
||||||
|
for sym in key.split('/'):
|
||||||
|
node = node._children[sym]
|
||||||
|
if node._content is None:
|
||||||
|
raise KeyError(key)
|
||||||
|
return node._content
|
||||||
|
except KeyError:
|
||||||
|
raise KeyError(key)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister(self, method):
|
||||||
|
self.logger.info("Unregister %s", method.__name__)
|
||||||
|
if method in self.registry:
|
||||||
|
content = self.registry[method]
|
||||||
|
clean_idx = None
|
||||||
|
for idx, content_obj in enumerate(content.parent._content):
|
||||||
|
if method == content_obj.method:
|
||||||
|
clean_idx = idx
|
||||||
|
break
|
||||||
|
if clean_idx is not None:
|
||||||
|
del content.parent._content[clean_idx]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def fire(self, topic: str, **kwargs) -> None:
|
||||||
|
|
||||||
|
self.logger.info("EMIT EVENT %s", topic)
|
||||||
|
|
||||||
|
cleanup_methods = []
|
||||||
|
for content_array in self.iter_match(topic):
|
||||||
|
|
||||||
|
print(content_array)
|
||||||
|
cleanup = []
|
||||||
|
for idx, content_obj in enumerate(content_array):
|
||||||
|
|
||||||
|
if inspect.iscoroutinefunction(content_obj.method):
|
||||||
|
if hasattr(content_obj.method, "future"):
|
||||||
|
|
||||||
|
self.cbpi.app.loop.create_task(content_obj.method(**kwargs, future=content_obj.method.future, topic=topic))
|
||||||
|
else:
|
||||||
|
self.cbpi.app.loop.create_task(content_obj.method(**kwargs, topic = topic))
|
||||||
|
else:
|
||||||
|
if hasattr(content_obj.method, "future"):
|
||||||
|
content_obj.method(**kwargs, future=content_obj.method.future, topic=topic)
|
||||||
|
else:
|
||||||
|
content_obj.method(**kwargs, topic = topic)
|
||||||
|
|
||||||
|
if content_obj.once is True:
|
||||||
|
cleanup.append(idx)
|
||||||
|
for idx in cleanup:
|
||||||
|
del content_array[idx]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def iter_match(self, topic):
|
||||||
|
|
||||||
|
lst = topic.split('/')
|
||||||
|
normal = not topic.startswith('$')
|
||||||
|
|
||||||
|
def rec(node, i=0):
|
||||||
|
if i == len(lst):
|
||||||
|
if node._content is not None:
|
||||||
|
yield node._content
|
||||||
|
else:
|
||||||
|
part = lst[i]
|
||||||
|
if part in node._children:
|
||||||
|
for content in rec(node._children[part], i + 1):
|
||||||
|
yield content
|
||||||
|
if '+' in node._children and (normal or i > 0):
|
||||||
|
for content in rec(node._children['+'], i + 1):
|
||||||
|
yield content
|
||||||
|
if '#' in node._children and (normal or i > 0):
|
||||||
|
content = node._children['#']._content
|
||||||
|
if content is not None:
|
||||||
|
yield content
|
||||||
|
|
||||||
|
return rec(self._root)
|
|
@ -12,36 +12,29 @@ class CustomLogic(CBPiKettleLogic):
|
||||||
running = True
|
running = True
|
||||||
|
|
||||||
|
|
||||||
async def wait_for_event(self, topic, timeout=None):
|
async def wait_for_event(self, topic, callback=None, timeout=None):
|
||||||
|
|
||||||
|
|
||||||
future_obj = self.cbpi.app.loop.create_future()
|
future_obj = self.cbpi.app.loop.create_future()
|
||||||
|
|
||||||
async def callback(id, **kwargs):
|
|
||||||
print("---------------------------------- CALLBACK ----------------")
|
|
||||||
print(kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
|
async def default_callback(id, **kwargs):
|
||||||
if int(id) == 1:
|
future_obj.set_result("HELLO")
|
||||||
self.cbpi.bus.unregister(callback)
|
|
||||||
future_obj.set_result("HELLO")
|
|
||||||
elif int(id) == 2:
|
|
||||||
self.cbpi.bus.unregister(callback)
|
|
||||||
else:
|
|
||||||
print("ID", id)
|
|
||||||
|
|
||||||
|
|
||||||
|
if callback is None:
|
||||||
print("TOPIC", topic)
|
self.cbpi.bus.register(topic=topic, method=default_callback)
|
||||||
self.cbpi.bus.register(topic=topic, method=callback)
|
else:
|
||||||
|
callback.future = future_obj
|
||||||
|
self.cbpi.bus.register(topic=topic, method=callback)
|
||||||
|
|
||||||
if timeout is not None:
|
if timeout is not None:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print("----> WAIT FOR FUTURE")
|
print("----> WAIT FOR FUTURE")
|
||||||
await asyncio.wait_for(future_obj, timeout=10.0)
|
await asyncio.wait_for(future_obj, timeout=timeout)
|
||||||
print("------> RETURN RESULT")
|
print("------> TIMEOUT")
|
||||||
return future_obj.result()
|
return future_obj.result()
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
print('timeout!')
|
print('timeout!')
|
||||||
|
@ -54,7 +47,13 @@ class CustomLogic(CBPiKettleLogic):
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
|
||||||
result = await self.wait_for_event("actor/+/on")
|
|
||||||
|
async def my_callback(id, **kwargs):
|
||||||
|
self.cbpi.bus.unregister(my_callback)
|
||||||
|
kwargs["future"].set_result("AMAZING")
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
result = await self.wait_for_event("actor/+/on", callback=my_callback)
|
||||||
print("THE RESULT", result)
|
print("THE RESULT", result)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@ import asyncio
|
||||||
from ._scheduler import Scheduler
|
from ._scheduler import Scheduler
|
||||||
|
|
||||||
|
|
||||||
async def create_scheduler(*, close_timeout=0.1, limit=100,
|
async def create_scheduler(cbpi,*, close_timeout=0.1, limit=100,
|
||||||
pending_limit=10000, exception_handler=None):
|
pending_limit=10000, exception_handler=None):
|
||||||
if exception_handler is not None and not callable(exception_handler):
|
if exception_handler is not None and not callable(exception_handler):
|
||||||
raise TypeError('A callable object or None is expected, '
|
raise TypeError('A callable object or None is expected, '
|
||||||
'got {!r}'.format(exception_handler))
|
'got {!r}'.format(exception_handler))
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
return Scheduler(loop=loop, close_timeout=close_timeout,
|
return Scheduler(cbpi=cbpi,loop=loop, close_timeout=close_timeout,
|
||||||
limit=limit, pending_limit=pending_limit,
|
limit=limit, pending_limit=pending_limit,
|
||||||
exception_handler=exception_handler)
|
exception_handler=exception_handler)
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,10 @@ else: # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
class Scheduler(*bases):
|
class Scheduler(*bases):
|
||||||
def __init__(self, *, close_timeout, limit, pending_limit,
|
def __init__(self, cbpi, *, close_timeout, limit, pending_limit,
|
||||||
exception_handler, loop):
|
exception_handler, loop):
|
||||||
self._loop = loop
|
self._loop = loop
|
||||||
|
self.cbpi = cbpi
|
||||||
self._jobs = set()
|
self._jobs = set()
|
||||||
self._close_timeout = close_timeout
|
self._close_timeout = close_timeout
|
||||||
self._limit = limit
|
self._limit = limit
|
||||||
|
@ -111,6 +112,9 @@ class Scheduler(*bases):
|
||||||
return self._exception_handler
|
return self._exception_handler
|
||||||
|
|
||||||
def _done(self, job):
|
def _done(self, job):
|
||||||
|
|
||||||
|
print("JOB DONE")
|
||||||
|
self.cbpi.bus.fire("job/done", key=job.name)
|
||||||
self._jobs.discard(job)
|
self._jobs.discard(job)
|
||||||
if not self.pending_count:
|
if not self.pending_count:
|
||||||
return
|
return
|
||||||
|
@ -127,6 +131,13 @@ class Scheduler(*bases):
|
||||||
new_job._start()
|
new_job._start()
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
def is_running(self, name):
|
||||||
|
|
||||||
|
for j in self._jobs:
|
||||||
|
if name == j.name:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
async def _wait_failed(self):
|
async def _wait_failed(self):
|
||||||
# a coroutine for waiting failed tasks
|
# a coroutine for waiting failed tasks
|
||||||
# without awaiting for failed tasks async raises a warning
|
# without awaiting for failed tasks async raises a warning
|
||||||
|
|
|
@ -40,9 +40,9 @@ def atomic(coro):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def setup(app, **kwargs):
|
def setup(app, cbpi, **kwargs):
|
||||||
async def on_startup(app):
|
async def on_startup(app):
|
||||||
app['AIOJOBS_SCHEDULER'] = await create_scheduler(**kwargs)
|
app['AIOJOBS_SCHEDULER'] = await create_scheduler(cbpi, **kwargs)
|
||||||
|
|
||||||
async def on_cleanup(app):
|
async def on_cleanup(app):
|
||||||
await app['AIOJOBS_SCHEDULER'].close()
|
await app['AIOJOBS_SCHEDULER'].close()
|
||||||
|
|
2
main2.py
2
main2.py
|
@ -1,6 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from core.eventbus import EventBus
|
from core.eventbus3 import EventBus
|
||||||
|
|
||||||
|
|
||||||
async def waiter(event):
|
async def waiter(event):
|
||||||
|
|
Loading…
Reference in a new issue