summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/add-frontend-alive-check2
-rw-r--r--src/leap/bitmask/app.py3
-rw-r--r--src/leap/bitmask/backend/backend.py24
-rw-r--r--src/leap/bitmask/backend/leapbackend.py4
-rw-r--r--src/leap/bitmask/backend_app.py5
5 files changed, 32 insertions, 6 deletions
diff --git a/changes/add-frontend-alive-check b/changes/add-frontend-alive-check
new file mode 100644
index 00000000..54f88798
--- /dev/null
+++ b/changes/add-frontend-alive-check
@@ -0,0 +1,2 @@
+- Stop the backend if the frontend process does not exist any more and backend
+ is not a daemon. Related to #5873.
diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py
index ab49ee37..37ded92a 100644
--- a/src/leap/bitmask/app.py
+++ b/src/leap/bitmask/app.py
@@ -180,7 +180,8 @@ def start_app():
flags_dict = flags_to_dict()
- backend = lambda: run_backend(opts.danger, flags_dict)
+ frontend_pid = os.getpid()
+ backend = lambda: run_backend(opts.danger, flags_dict, frontend_pid)
backend_process = multiprocessing.Process(target=backend, name='Backend')
backend_process.daemon = True
backend_process.start()
diff --git a/src/leap/bitmask/backend/backend.py b/src/leap/bitmask/backend/backend.py
index c895f8f5..67ffe35a 100644
--- a/src/leap/bitmask/backend/backend.py
+++ b/src/leap/bitmask/backend/backend.py
@@ -18,6 +18,8 @@ import json
import threading
import time
+import psutil
+
from twisted.internet import defer, reactor, threads
import zmq
@@ -39,12 +41,16 @@ class Backend(object):
PORT = '5556'
BIND_ADDR = "tcp://127.0.0.1:%s" % PORT
- def __init__(self):
+ PING_INTERVAL = 2 # secs
+
+ def __init__(self, frontend_pid=None):
"""
Backend constructor, create needed instances.
"""
self._signaler = Signaler()
+ self._frontend_pid = frontend_pid
+
self._do_work = threading.Event() # used to stop the worker thread.
self._zmq_socket = None
@@ -81,6 +87,8 @@ class Backend(object):
Note: we use a simple while since is less resource consuming than a
Twisted's LoopingCall.
"""
+ pid = self._frontend_pid
+ check_wait = 0
while self._do_work.is_set():
# Wait for next request from client
try:
@@ -93,6 +101,20 @@ class Backend(object):
raise
time.sleep(0.01)
+ check_wait += 0.01
+ if pid is not None and check_wait > self.PING_INTERVAL:
+ check_wait = 0
+ self._check_frontend_alive()
+
+ def _check_frontend_alive(self):
+ """
+ Check if the frontend is alive and stop the backend if it is not.
+ """
+ pid = self._frontend_pid
+ if pid is not None and not psutil.pid_exists(pid):
+ logger.critical("The frontend is down!")
+ self.stop()
+
def _stop_reactor(self):
"""
Stop the Twisted reactor, but first wait a little for some threads to
diff --git a/src/leap/bitmask/backend/leapbackend.py b/src/leap/bitmask/backend/leapbackend.py
index d3c4fcda..6b0328ca 100644
--- a/src/leap/bitmask/backend/leapbackend.py
+++ b/src/leap/bitmask/backend/leapbackend.py
@@ -36,11 +36,11 @@ class LeapBackend(Backend):
"""
Backend server subclass, used to implement the API methods.
"""
- def __init__(self, bypass_checks=False):
+ def __init__(self, bypass_checks=False, frontend_pid=None):
"""
Constructor for the backend.
"""
- Backend.__init__(self)
+ Backend.__init__(self, frontend_pid)
self._settings = Settings()
diff --git a/src/leap/bitmask/backend_app.py b/src/leap/bitmask/backend_app.py
index 5c0e4803..716ae4a7 100644
--- a/src/leap/bitmask/backend_app.py
+++ b/src/leap/bitmask/backend_app.py
@@ -44,7 +44,7 @@ def signal_handler(signum, frame):
logger.debug("{0}: SIGNAL #{1} catched.".format(pname, signum))
-def run_backend(bypass_checks, flags_dict):
+def run_backend(bypass_checks, flags_dict, frontend_pid=None):
"""
Run the backend for the application.
@@ -59,5 +59,6 @@ def run_backend(bypass_checks, flags_dict):
dict_to_flags(flags_dict)
- backend = LeapBackend(bypass_checks=bypass_checks)
+ backend = LeapBackend(bypass_checks=bypass_checks,
+ frontend_pid=frontend_pid)
backend.run()