Skip to content
Snippets Groups Projects
Commit 48730129 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

daemon cleaned up

parent ba371b1b
No related branches found
No related tags found
No related merge requests found
Exception handling
==================
Satella provides a rich functionality to register exception hooks.
Writing your own exception handlers
-----------------------------------
To write your own exception handlers, subclass the following class:
.. autoclass:: satella.exception_handling.BaseExceptionHandler
:members:
......@@ -14,6 +14,7 @@ Welcome to satella's documentation!
coding/concurrent
instrumentation/traceback
instrumentation/metrics
exception_handling/index
json
posix
recipes
......
# coding=UTF-8
"""
UNIX things
POSIX things
"""
from __future__ import print_function, absolute_import, division
import logging
import os
from .daemon import daemonize
from .pidlock import AcquirePIDLock
from .signals import hang_until_sig
logger = logging.getLogger(__name__)
__all__ = [
'daemonize',
......@@ -27,6 +23,7 @@ def is_running_as_root():
Is this process running as root?
Checks whether EUID is 0
:return: bool
"""
return os.geteuid() == 0
......
......@@ -20,6 +20,9 @@ logger = logging.getLogger(__name__)
DEVNULL = '/dev/null'
__all__ = ['daemonize']
def daemonize(exit_via: tp.Callable = sys.exit,
redirect_std_to_devnull: bool = True,
uid: tp.Optional[int] = None,
......@@ -58,10 +61,10 @@ def daemonize(exit_via: tp.Callable = sys.exit,
_parse_ug(gid, grp, 'gr_gid', os.setegid)
def _parse_ug(no, module, fieldname, osfun):
def _parse_ug(no, module, field_name, osfun):
if no is not None:
if isinstance(no, str):
no = getattr(module.getpwnam(no), fieldname)
no = getattr(module.getpwnam(no), field_name)
osfun(no)
......
......@@ -24,13 +24,17 @@ class AcquirePIDLock:
Usage:
with AcquirePIDLock('myservice.pid'):
>>> with AcquirePIDLock('myservice.pid'):
>>> ... rest of code ..
.. rest of code ..
Or alternatively
Exiting the context manager deletes the file.
>>> pid_lock = AcquirePIDLock('myservice.pid')
>>> pid_lock.acquire()
>>> ...
>>> pid_lock.release()
The constructor doesn't throw, __enter__ does, one of:
The constructor doesn't throw, __enter__ or acquire() does, one of:
* AcquirePIDLock.FailedToAcquire - base class for errors. Thrown if can't read the file
* AcquirePIDLock.LockIsHeld - lock is already held. This has two attributes - pid (int), the PID of holder,
......@@ -55,8 +59,18 @@ class AcquirePIDLock:
self.fileno = None
def _acquire(self):
"""The mechanical process of acquisition"""
def release(self):
if self.fileno is not None:
os.close(self.fileno)
os.unlink(self.path)
def acquire(self):
"""
Acquire the PID lock
:raises LockIsHeld: if lock if held
:raises FailedToAcquire: if for example a directory exists in that place
"""
try:
self.fileno = os.open(self.path, os.O_CREAT | os.O_EXCL)
except (IOError, OSError):
......@@ -69,7 +83,7 @@ class AcquirePIDLock:
'PID file found but doesn''t have an int, skipping')
return
except IOError as e:
raise FailedToAcquire()
raise FailedToAcquire(repr(e))
# Is this process alive?
try:
......@@ -81,17 +95,15 @@ class AcquirePIDLock:
def __enter__(self):
try:
self._acquire()
self.acquire()
except LockIsHeld as e:
if self.delete_on_dead and (not e.is_alive):
os.unlink(self.path)
self._acquire()
self.acquire()
else:
raise
self.success = True
def __exit__(self, exc_type, exc_val, exc_tb):
if self.fileno is not None:
os.close(self.fileno)
os.unlink(self.path)
self.release()
......@@ -14,10 +14,14 @@ def __sighandler(a, b):
end = True
def hang_until_sig(extra_signals: tp.Optional[tp.List] = None):
"""Will hang until this process receives SIGTERM or SIGINT.
def hang_until_sig(extra_signals: tp.Optional[tp.List[int]] = None):
"""
Will hang until this process receives SIGTERM or SIGINT.
If you pass extra signal IDs (signal.SIG*) with extra_signals,
then also on those signals this call will release."""
then also on those signals this call will release.
:param extra_signals: a list of extra signals to listen to
"""
extra_signals = extra_signals or []
global end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment