Files
revng-revng/python/revng/daemon/manager.py
2022-09-26 18:09:01 +02:00

72 lines
2.2 KiB
Python

#
# This file is distributed under the MIT License. See LICENSE.md for details.
#
import logging
import os
from abc import ABC, abstractmethod
from pathlib import Path
from tempfile import mkdtemp
from typing import Optional
from revng.api.listenable_manager import EventType, ListenableManager
from revng.api.manager import Manager
from revng.support import AnyPath
class BaseListener(ABC):
def __init__(self, fifo_path: Path):
self.fifo = open(fifo_path, "w") # noqa: SIM115
@abstractmethod
def __call__(self, manager: Manager, type_: EventType):
pass
def write_fifo(self, content: str):
try:
self.fifo.write(content)
self.fifo.flush()
except (BrokenPipeError, FileNotFoundError, PermissionError, TimeoutError) as e:
logging.warn(
f"Encountered error when writing to notification pipe: {repr(e)}",
)
def __del__(self):
self.fifo.close()
class BeginListener(BaseListener):
def __call__(self, manager: Manager, type_: EventType):
assert type_ == EventType.BEGIN
begin_step = manager.get_step("begin")
assert begin_step is not None
tmpdir = mkdtemp(prefix="revng-daemon-begin-")
begin_step.save(tmpdir)
self.write_fifo(f"PUSH begin {tmpdir}\n")
class ContextListener(BaseListener):
def __call__(self, manager: Manager, type_: EventType):
assert type_ == EventType.CONTEXT
tmpdir = mkdtemp(prefix="revng-daemon-context-")
manager.save_context(tmpdir)
self.write_fifo(f"PUSH context {tmpdir}\n")
def make_manager(workdir: Optional[AnyPath]) -> Manager:
if "REVNG_NOTIFY_FIFOS" not in os.environ:
return Manager(workdir)
manager = ListenableManager(workdir)
for fifo_definition in os.environ["REVNG_NOTIFY_FIFOS"].split(","):
fifo_path, string_type = fifo_definition.split(":", 1)
if string_type == "begin":
manager.add_event_listener(EventType.BEGIN, BeginListener(Path(fifo_path)))
elif string_type == "context":
manager.add_event_listener(EventType.CONTEXT, ContextListener(Path(fifo_path)))
else:
logging.warn(f"Unknown event type specified for fifo: {string_type}")
return manager