Files
revng-revng/python/revng/internal/daemon/event_manager.py
Giacomo Vercesi ca26c06ecc EventManager: fix save logic
Fix the save logic of `EventManager` where an erroneous comparison lead
to the saves never being triggered.
2025-02-25 09:18:24 +01:00

76 lines
2.4 KiB
Python

#
# This file is distributed under the MIT License. See LICENSE.md for details.
#
import time
from enum import StrEnum, auto
from functools import wraps
from threading import Thread
from typing import Callable, Iterable, cast
from revng.internal.api import Manager
class EventType(StrEnum):
BEGIN = auto()
CONTEXT = auto()
PRODUCE = auto()
def emit_event(event_type: EventType):
"""Decorator for allowing a GraphQL handler to emit an event after handling.
This is expected to wrap handler-like function where the second argument is
GraphQL's info object"""
def decorator(f):
@wraps(f)
async def inner(*args, **kwargs):
result = await f(*args, **kwargs)
context = args[1].context
if "event_manager" in context:
context["event_manager"].handle_event(event_type)
return result
return inner
return decorator
class EventManager(Thread):
def __init__(self, manager: Manager, save_hooks: Iterable[Callable[[Manager, str], None]]):
super().__init__()
self.manager = manager
self.save_hooks = save_hooks
self.running = True
self._interval = 120 # 2 minutes
self.last_save: float = time.time()
self.last_event: float | None = None
self.credentials: str | None = None
def run(self):
while self.running:
# This loop will call manager.save every 2 minutes if changes have been made in the
# meantime. This is to prevent the manager from lagging on every change. Some changes
# related to speeding up the pipeline manager from saving (e.g. detecting dirtiness in
# containers) need to be implemented before this can be dropped
if self.last_save + self._interval < time.time() and (
self.last_event is not None and self.last_event > self.last_save
):
self.save()
self.last_save = time.time()
time.sleep(10)
def save(self) -> bool:
result = self.manager.save()
if result:
for hook in self.save_hooks:
hook(self.manager, cast(str, self.credentials))
return result
def handle_event(self, type_: EventType):
self.last_event = time.time()
def set_credentials(self, credentials: str):
self.credentials = credentials
self.manager.set_storage_credentials(credentials)