browsertrix/backend/btrixcloud/profile_job.py
Ilya Kreymer b11a5f136a profile browser deletion/removal:
- ensure profile browser DELETE command is working
- ensure profile browser job expires if no initial ping
- logging: print exception for base job if init fails
2022-08-02 18:31:33 -07:00

70 lines
2.2 KiB
Python

""" entry point for job which manages a browser (eg. for profile creation) """
import os
import signal
import asyncio
from abc import ABC, abstractmethod
# =============================================================================
class ProfileJob(ABC):
""" Browser run job """
job_id = None
def __init__(self):
super().__init__()
self.loop = asyncio.get_event_loop()
params = {
"storage_name": os.environ.get("STORAGE_NAME"),
"storage_path": os.environ.get("STORE_PATH") or "",
"url": os.environ.get("START_URL"),
"profile_filename": os.environ.get("PROFILE_PATH") or "",
}
self.idle_timeout = int(os.environ["IDLE_TIMEOUT"])
self.loop.add_signal_handler(signal.SIGUSR1, self.ping_handler)
self.loop.add_signal_handler(signal.SIGALRM, self.timeout_handler)
self.loop.add_signal_handler(signal.SIGTERM, self.exit_handler)
self.loop.create_task(self.async_init("profilebrowser.yaml", params))
print(f"running browser for at least {self.idle_timeout} secs", flush=True)
signal.setitimer(signal.ITIMER_REAL, self.idle_timeout, 0)
async def async_init(self, template, params):
""" async init, overridable by subclass """
await self.init_job_objects(template, params)
@abstractmethod
async def init_job_objects(self, filename, params):
""" base for creating objects """
@abstractmethod
async def delete_job_objects(self, job_id):
""" base for deleting objects """
def ping_handler(self, *_args):
""" handle custom signal as ping, extend shutdown timer """
print(f"signal received, extending timer {self.idle_timeout} secs", flush=True)
signal.setitimer(signal.ITIMER_REAL, self.idle_timeout, 0)
def exit_handler(self):
""" handle SIGTERM """
print("sigterm: shutting down browser...", flush=True)
self._do_exit()
def timeout_handler(self):
""" handle SIGALRM """
print("sigalrm: timer expired ending idle browser...", flush=True)
self._do_exit()
def _do_exit(self):
self.loop.create_task(self.delete_job_objects(f"browser={self.job_id}"))