summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Alejandro <ivanalejandro0@gmail.com>2014-07-24 12:54:12 -0300
committerIvan Alejandro <ivanalejandro0@gmail.com>2014-12-19 17:15:55 -0300
commitdf160c0d44e8d0439d54313f097b2a4d9ada7357 (patch)
treec3d2cb9f68f696bc9377dbaf20897cf0a560afde
parent30b02e9153b21d177bf0f79e7132157bf25b636d (diff)
Allow frontend and backend to be run separately.
Add the 'check_online' method to check whether the backend is accessible or not. Reduce the wait for running threads timeout on quit. Add retry feature to the backend requests send.
-rw-r--r--src/leap/bitmask/app.py31
-rw-r--r--src/leap/bitmask/backend/backend.py2
-rw-r--r--src/leap/bitmask/backend/backend_proxy.py30
-rw-r--r--src/leap/bitmask/backend/signaler.py1
-rw-r--r--src/leap/bitmask/backend_app.py13
-rw-r--r--src/leap/bitmask/frontend_app.py2
-rw-r--r--src/leap/bitmask/gui/app.py1
7 files changed, 64 insertions, 16 deletions
diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py
index 87f22d88..ef156671 100644
--- a/src/leap/bitmask/app.py
+++ b/src/leap/bitmask/app.py
@@ -44,6 +44,7 @@ import os
import sys
+from leap.bitmask.backend.backend_proxy import BackendProxy
from leap.bitmask.backend.utils import generate_certificates
from leap.bitmask import __version__ as VERSION
@@ -178,19 +179,29 @@ def start_app():
logger.info('Starting app')
- generate_certificates()
+ backend = BackendProxy()
+ backend_running = backend.check_online()
- flags_dict = flags_to_dict()
+ logger.debug("Backend online: {0}".format(backend_running))
+
+ if not backend_running:
+ generate_certificates()
- frontend_pid = os.getpid()
- backend = lambda: run_backend(opts.danger, flags_dict, frontend_pid)
- backend_process = multiprocessing.Process(target=backend, name='Backend')
- # we don't set the 'daemon mode' since we need to start child processes in
- # the backend
- # backend_process.daemon = True
- backend_process.start()
+ flags_dict = flags_to_dict()
- run_frontend(options, flags_dict, backend_pid=backend_process.pid)
+ backend_pid = None
+ if not backend_running:
+ frontend_pid = os.getpid()
+ backend = lambda: run_backend(opts.danger, flags_dict, frontend_pid)
+ backend_process = multiprocessing.Process(target=backend,
+ name='Backend')
+ # we don't set the 'daemon mode' since we need to start child processes
+ # in the backend
+ # backend_process.daemon = True
+ backend_process.start()
+ backend_pid = backend_process.pid
+
+ run_frontend(options, flags_dict, backend_pid=backend_pid)
if __name__ == "__main__":
diff --git a/src/leap/bitmask/backend/backend.py b/src/leap/bitmask/backend/backend.py
index 37535f37..75eff8a9 100644
--- a/src/leap/bitmask/backend/backend.py
+++ b/src/leap/bitmask/backend/backend.py
@@ -135,7 +135,7 @@ class Backend(object):
i.e.:
use threads.deferToThread(this_method) instead of this_method()
"""
- wait_max = 5 # seconds
+ wait_max = 3 # seconds
wait_step = 0.5
wait = 0
while self._ongoing_defers and wait < wait_max:
diff --git a/src/leap/bitmask/backend/backend_proxy.py b/src/leap/bitmask/backend/backend_proxy.py
index e2611251..9de3501e 100644
--- a/src/leap/bitmask/backend/backend_proxy.py
+++ b/src/leap/bitmask/backend/backend_proxy.py
@@ -67,6 +67,7 @@ class BackendProxy(object):
socket.curve_serverkey = public
socket.setsockopt(zmq.RCVTIMEO, 1000)
+ socket.setsockopt(zmq.LINGER, 0) # Terminate early
socket.connect(self.SERVER)
self._socket = socket
@@ -75,8 +76,23 @@ class BackendProxy(object):
self._call_queue = Queue.Queue()
self._worker_caller = threading.Thread(target=self._worker)
+
+ def start(self):
self._worker_caller.start()
+ def check_online(self):
+ """
+ Return whether the backend is accessible or not.
+ You don't need to do `run` in order to use this.
+
+ :rtype: bool
+ """
+ # we use a small timeout in order to response quickly if the backend is
+ # offline
+ self._send_request(PING_REQUEST, retry=False, timeout=500)
+ self._socket.close()
+ return self.online
+
def _worker(self):
"""
Worker loop that processes the Queue of pending requests to do.
@@ -150,7 +166,7 @@ class BackendProxy(object):
if api_method == STOP_REQUEST:
self._call_queue.put(STOP_REQUEST)
- def _send_request(self, request):
+ def _send_request(self, request, retry=True, timeout=None):
"""
Send the given request to the server.
This is used from a thread safe loop in order to avoid sending a
@@ -158,6 +174,10 @@ class BackendProxy(object):
:param request: the request to send.
:type request: str
+ :param retry: whether we should retry or not in case of timeout.
+ :type retry: bool
+ :param timeout: a custom timeout (milliseconds) to wait for a response.
+ :type timeout: int
"""
# logger.debug("Sending request to backend: {0}".format(request))
self._socket.send(request)
@@ -166,10 +186,16 @@ class BackendProxy(object):
poll.register(self._socket, zmq.POLLIN)
reply = None
+
tries = 0
+ if not retry:
+ tries = self.POLL_TRIES + 1 # this means: no retries left
+
+ if timeout is None:
+ timeout = self.POLL_TIMEOUT
while True:
- socks = dict(poll.poll(self.POLL_TIMEOUT))
+ socks = dict(poll.poll(timeout))
if socks.get(self._socket) == zmq.POLLIN:
reply = self._socket.recv()
break
diff --git a/src/leap/bitmask/backend/signaler.py b/src/leap/bitmask/backend/signaler.py
index 574bfa71..43cba994 100644
--- a/src/leap/bitmask/backend/signaler.py
+++ b/src/leap/bitmask/backend/signaler.py
@@ -60,6 +60,7 @@ class Signaler(object):
socket.curve_serverkey = public
socket.setsockopt(zmq.RCVTIMEO, 1000)
+ socket.setsockopt(zmq.LINGER, 0) # Terminate early
socket.connect(self.SERVER)
self._socket = socket
diff --git a/src/leap/bitmask/backend_app.py b/src/leap/bitmask/backend_app.py
index 716ae4a7..ce75dc80 100644
--- a/src/leap/bitmask/backend_app.py
+++ b/src/leap/bitmask/backend_app.py
@@ -22,6 +22,8 @@ import multiprocessing
import signal
from leap.bitmask.backend.leapbackend import LeapBackend
+from leap.bitmask.backend.utils import generate_certificates
+from leap.bitmask.logs.utils import create_logger
from leap.bitmask.util import dict_to_flags
logger = logging.getLogger(__name__)
@@ -44,7 +46,7 @@ def signal_handler(signum, frame):
logger.debug("{0}: SIGNAL #{1} catched.".format(pname, signum))
-def run_backend(bypass_checks, flags_dict, frontend_pid=None):
+def run_backend(bypass_checks=False, flags_dict=None, frontend_pid=None):
"""
Run the backend for the application.
@@ -57,8 +59,15 @@ def run_backend(bypass_checks, flags_dict, frontend_pid=None):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal_handler)
- dict_to_flags(flags_dict)
+ if flags_dict is not None:
+ dict_to_flags(flags_dict)
backend = LeapBackend(bypass_checks=bypass_checks,
frontend_pid=frontend_pid)
backend.run()
+
+
+if __name__ == '__main__':
+ logger = create_logger(debug=True)
+ generate_certificates()
+ run_backend()
diff --git a/src/leap/bitmask/frontend_app.py b/src/leap/bitmask/frontend_app.py
index 909005f0..b0a149f9 100644
--- a/src/leap/bitmask/frontend_app.py
+++ b/src/leap/bitmask/frontend_app.py
@@ -54,7 +54,7 @@ def signal_handler(window, pid, signum, frame):
window.quit()
-def run_frontend(options, flags_dict, backend_pid):
+def run_frontend(options, flags_dict, backend_pid=None):
"""
Run the GUI for the application.
diff --git a/src/leap/bitmask/gui/app.py b/src/leap/bitmask/gui/app.py
index eb1a58d5..75dc4a38 100644
--- a/src/leap/bitmask/gui/app.py
+++ b/src/leap/bitmask/gui/app.py
@@ -41,6 +41,7 @@ class App(QtGui.QWidget):
self.settings = LeapSettings()
self.backend = BackendProxy()
+ self.backend.start()
self.signaler = LeapSignaler()
self.signaler.start()