Example #1
0
 def __init__(self):
     self._codec = _default_codec()
     self.lock = threading.Condition()
     self.events = Queue()
     self.token_counter = 0
     self.sites = {}  # host, port -> site
     self.event_thread = _EventProcessor(self)
     self.event_thread.daemon = True
     self.event_thread.start()
     self._codec = _default_codec()
     self.log = Logger("quark.runtime")
Example #2
0
 def logger(self, topic):
     return Logger(topic)
Example #3
0
class ThreadedRuntime(object):


    def __init__(self):
        self._codec = _default_codec()
        self.lock = threading.Condition()
        self.events = Queue()
        self.token_counter = 0
        self.sites = {}  # host, port -> site
        self.event_thread = _EventProcessor(self)
        self.event_thread.daemon = True
        self.event_thread.start()
        self._codec = _default_codec()
        self.log = Logger("quark.runtime")

    def acquire(self):
        self.lock.acquire()

    def release(self):
        self.lock.release()

    def _notify(self):
        self.lock.notify_all()

    def wait(self, timeoutInSeconds):
        self.lock.wait(timeoutInSeconds)

    def _add_event_source(self, name):
        with self.event_thread.token_lock:
            token = (self.token_counter, name, self)
            self.token_counter += 1
            self.event_thread.live.add(token)
        return token

    def _remove_event_source(self, token):
        def remove_token():
            with self.event_thread.token_lock:
                self.event_thread.live.remove(token)
        self.events.put((remove_token, (), {}))

    def open(self, url, handler):
        def pump_websocket(runtime, url, handler):
            ws = _QuarkWS(runtime, url, handler)
            try:
                ws.connect()
                ws.run_forever()
            except Exception as ex:
                runtime.log.debug("websocket pump exception: %s" % ex)
                import quark
                runtime.events.put((handler.onWSError, (ws, quark.WSError(str(ex))), {}))
                runtime.events.put((handler.onWSFinal, (ws,), {}))
        try:
            self.acquire()
            thread = threading.Thread(target=Tracker(self, "client websocket", pump_websocket), args=(self, url, handler))
            thread.setDaemon(True)
            thread.start()
        finally:
            self.release()

    def request(self, request, handler):
        try:
            self.acquire()
            thread = threading.Thread(target=Tracker(self, "request", _QuarkRequest(self, request, handler)))
            thread.setDaemon(True)
            thread.start()
        finally:
            self.release()

    def schedule(self, handler, delayInSeconds):
        def run_scheduled(runtime, handler, delayInSeconds):
            time.sleep(delayInSeconds)
            runtime.events.put((handler.onExecute, [runtime], {}))
        try:
            self.acquire()
            thread = threading.Thread(target=Tracker(self, "task", run_scheduled),
                                      args=(self, handler, delayInSeconds))
            thread.setDaemon(True)
            thread.start()
        finally:
            self.release()

    def serveHTTP(self, url, servlet):
        url = Url(url)
        import quark
        if url.scheme not in ["http", "https"]:
            self.events.put((servlet.onServletError, (url.url, quark.ServletError(url.scheme + " is not supported")), {}))
            return
        if url.scheme in ["https"]:
            self.events.put((servlet.onServletError, (url.url, quark.ServletError(url.scheme + " is not supported yet")), {}))
            return
        container = self._make_container(url)
        container.add(HttpServletAdapter(self, url, servlet))

    def serveWS(self, url, servlet):
        url = Url(url)
        import quark
        if url.scheme not in ["ws", "wss"]:
            self.events.put((servlet.onServletError, (url.url, quark.ServletError(url.scheme + " is not supported")), {}))
            return
        if url.scheme in ["wss"]:
            self.events.put((servlet.onServletError, (url.url, quark.ServletError(url.scheme + " is not supported yet")), {}))
            return
        container = self._make_container(url)
        container.add(WSServletAdapter(self, url, servlet))

    def _make_container(self, url):
        try:
            with self.lock:
                server = self.sites.get((url.host, url.port))
                if not server:
                    # synchronous bind and listen...
                    server = _QuarkWSGIServer((url.host, url.port), _QuarkWSGIRequestHandler)
                    url.port = server.server_port
                    app = _QuarkWSGIApp(self, url)
                    server.set_app(app)
                    server.initialize_websockets_manager()
                    thread = threading.Thread(target = Tracker(self, "container", server.serve_forever))
                    thread.setDaemon(True)
                    thread.start()
                    self.sites[url.host, url.port] = server
                return server.application
        except Exception as exc:
            print(traceback.format_exc())
            return _NoApplication(self, url, exc)

    def respond(self, request, response):
        response._responded = True

    def fail(self, message):
        self.event_thread.die_now = True
        if False:  # Set to True to enable traceback printing
            print("Traceback (most recent call last, up to fail(...)):")
            traceback.print_stack(sys._getframe(1))
            # Note: sys._getframe(1) works on CPython, Jython, and PyPy. Need to test on IronPython etc.
        sys.stderr.write(message + "\n")
        os._exit(1)

    def codec(self):
        return self._codec

    def logger(self, topic):
        return Logger(topic)

    def now(self):
        return long(time.time() * 1000)

    def sleep(self, seconds):
        time.sleep(seconds)

    def uuid(self):
        return str(uuid.uuid4())

    def callSafely(self, unary_callable, default):
        try:
            import quark
            return quark.callUnaryCallable(unary_callable, None)
        except:
            self.log.error("Exception while calling safely: "
                           + traceback.format_exc())
            return default