Beispiel #1
0
    def clutter_proc(self):
        try:
            from gi.repository import Clutter, GObject, Gtk, GtkClutter

            # explicit init seems to avoid strange thread sync/blocking issues
            GObject.threads_init()
            GtkClutter.init([])

            # create main window
            from mfp.gui.patch_window import PatchWindow
            self.appwin = PatchWindow()
            self.mfp = MFPCommand()

        except Exception as e:
            log.error("Fatal error during GUI startup")
            log.debug_traceback()
            return

        try:
            # direct logging to GUI log console
            Gtk.main()
        except Exception as e:
            log.error("Caught GUI exception:", e)
            log.debug_traceback()
            sys.stdout.flush()
Beispiel #2
0
    def dispatch_rpcdata(self, rpc_worker, rpcdata):
        try:
            json_data, peer_id = rpcdata
            obj = json.loads(json_data, object_hook=extended_decoder_hook)
        except Exception as e:
            log.error("Can't parse JSON for peer:", peer_id, json_data)
            log.debug_traceback()
            return True

        req = Request.from_dict(obj)

        # is someone waiting on this response?
        rpc_worker.data = "Request %s started" % req.request_id
        if req.is_response() and req.request_id in self.pending:
            rpc_worker.data = "Request %s processing response" % req.request_id
            oldreq = self.pending.get(req.request_id)
            del self.pending[req.request_id]
            oldreq.result = req.result
            oldreq.state = req.state
            oldreq.diagnostic = req.diagnostic
            with self.lock:
                self.condition.notify()
        elif req.is_request():
            rpc_worker.data = "Request %s calling local %s (%s)" % (
                req.request_id, req.method, req.params)
            # actually call the local handler
            self.handle_request(req, peer_id)
            # and send back the response
            rpc_worker.data = "Request %s sending response" % req.request_id
            if req.request_id is not None:
                self.put(req, peer_id)
        rpc_worker.data = "Request %s done (%s)" % (req.request_id, req.method)
        return True
Beispiel #3
0
    def remove(self, obj):
        try:
            if obj.scope is not None and obj.name is not None:
                self.unbind(obj.name, obj.scope)
            del self.objects[obj.obj_id]
        except KeyError:
            log.error("Error deleting obj", obj, "can't find key", obj.obj_id)
            log.debug_traceback()

        try:
            self.inlet_objects.remove(obj)
            self.dsp_inlets = [ p[0] for p in enumerate(self.inlet_objects)
                               if p[1] and p[1].init_type == 'inlet~' ]
            self.gui_params['dsp_inlets'] = self.dsp_inlets
        except ValueError:
            pass

        try:
            self.outlet_objects.remove(obj)
            self.dsp_outlets = [ p[0] for p in enumerate(self.outlet_objects)
                                if p[1] and p[1].init_type == 'outlet~' ]
            self.gui_params['dsp_outlets'] = self.dsp_outlets
        except ValueError:
            pass

        try:
            self.dispatch_objects.remove(obj)
        except ValueError:
            pass
Beispiel #4
0
    def call(self, target):
        try:
            m = getattr(target, self.method)
        except AttributeError as e:
            raise MethodCallError("Method '%s' not found for type '%s'" %
                                  (self.method, target.init_type))

        if callable(m):
            try:
                return m(*self.args, **self.kwargs)
            except Exception as e:
                log.debug("Error calling", self.method, "on", target)
                log.debug("args=%s, kwargs=%s" % (self.args, self.kwargs))
                log.debug_traceback()
                raise MethodCallError(
                    "Method '%s' for type '%s' raised exception '%s' %s" %
                    (self.method, target.init_type, e, type(e)))
        elif self.fallback:
            try:
                return self.fallback([self] + self.args, **self.kwargs)
            except Exception as e:
                raise MethodCallError(
                    "Method fallback '%s' for type '%s' raised exception '%s'"
                    % (self.method, target.init_type, e))
        else:
            log.debug("MethodCall.call():", target, self.method, m, type(m))
            raise MethodCallError("Method '%s' of type '%s' cannot be called" %
                                  (self.method, target.init_type))
Beispiel #5
0
    def call(self, target):
        try:
            m = getattr(target, self.method)
        except AttributeError as e:
            raise MethodCallError("Method '%s' not found for type '%s'" % (self.method, target.init_type))

        if callable(m):
            try:
                return m(*self.args, **self.kwargs)
            except Exception as e:
                log.debug("Error calling", self.method, "on", target)
                log.debug( "args=%s, kwargs=%s" % (self.args, self.kwargs))
                log.debug_traceback()
                raise MethodCallError("Method '%s' for type '%s' raised exception '%s' %s"
                                      % (self.method, target.init_type, e, type(e)))
        elif self.fallback:
            try:
                return self.fallback([self] + self.args, **self.kwargs)
            except Exception as e:
                raise MethodCallError("Method fallback '%s' for type '%s' raised exception '%s'"
                                      % (self.method, target.init_type, e))
        else:
            log.debug("MethodCall.call():", target, self.method, m, type(m))
            raise MethodCallError("Method '%s' of type '%s' cannot be called" 
                            % (self.method, target.init_type))
Beispiel #6
0
    def remove(self, obj):
        try:
            if obj.scope is not None and obj.name is not None:
                self.unbind(obj.name, obj.scope)
            del self.objects[obj.obj_id]
        except KeyError:
            log.error("Error deleting obj", obj, "can't find key", obj.obj_id)
            log.debug_traceback()

        try:
            self.inlet_objects.remove(obj)
            self.dsp_inlets = [ p[0] for p in enumerate(self.inlet_objects)
                               if p[1] and p[1].init_type == 'inlet~' ]
            self.gui_params['dsp_inlets'] = self.dsp_inlets
        except ValueError:
            pass

        try:
            self.outlet_objects.remove(obj)
            self.dsp_outlets = [ p[0] for p in enumerate(self.outlet_objects)
                                if p[1] and p[1].init_type == 'outlet~' ]
            self.gui_params['dsp_outlets'] = self.dsp_outlets
        except ValueError:
            pass

        try:
            self.dispatch_objects.remove(obj)
        except ValueError:
            pass
Beispiel #7
0
    def clutter_proc(self):
        try:
            from gi.repository import Clutter, GObject, Gtk, GtkClutter

            # explicit init seems to avoid strange thread sync/blocking issues
            GObject.threads_init()
            GtkClutter.init([])

            # create main window
            from mfp.gui.patch_window import PatchWindow
            self.appwin = PatchWindow()
            self.mfp = MFPCommand()

        except Exception as e:
            log.error("Fatal error during GUI startup")
            log.debug_traceback()
            return

        try:
            # direct logging to GUI log console
            Gtk.main()
        except Exception as e:
            log.error("Caught GUI exception:", e)
            log.debug_traceback()
            sys.stdout.flush()
Beispiel #8
0
    def dispatch_rpcdata(self, rpc_worker, rpcdata):
        try:
            json_data, peer_id = rpcdata
            obj = json.loads(json_data, object_hook=extended_decoder_hook)
        except Exception as e:
            log.error("Can't parse JSON for peer:", peer_id, json_data)
            log.debug_traceback()
            return True

        req = Request.from_dict(obj)

        # is someone waiting on this response?
        rpc_worker.data = "Request %s started" % req.request_id
        if req.is_response() and req.request_id in self.pending:
            rpc_worker.data = "Request %s processing response" % req.request_id
            oldreq = self.pending.get(req.request_id)
            del self.pending[req.request_id]
            oldreq.result = req.result
            oldreq.state = req.state
            oldreq.diagnostic = req.diagnostic
            with self.lock:
                self.condition.notify()
        elif req.is_request():
            rpc_worker.data = "Request %s calling local %s (%s)" % (req.request_id, req.method, req.params)
            # actually call the local handler
            self.handle_request(req, peer_id)
            # and send back the response
            rpc_worker.data = "Request %s sending response" % req.request_id
            if req.request_id is not None:
                self.put(req, peer_id)
        rpc_worker.data = "Request %s done (%s)" % (req.request_id, req.method)
        return True
Beispiel #9
0
 def _callback_wrapper(self, thunk):
     try:
         return thunk()
     except Exception as e:
         import traceback
         log.debug("Exception in GUI operation:", e)
         log.debug_traceback()
         return False
Beispiel #10
0
 def handler(stage, event):
     try:
         return self.input_mgr.handle_event(stage, event)
     except Exception as e:
         log.error("Error handling UI event", event)
         log.debug(e)
         log.debug_traceback()
         return False
Beispiel #11
0
 def _callback_wrapper(self, thunk):
     try:
         return thunk()
     except Exception as e:
         import traceback
         log.debug("Exception in GUI operation:", e)
         log.debug_traceback()
         return False
Beispiel #12
0
 def handler(stage, event):
     try:
         return self.input_mgr.handle_event(stage, event)
     except Exception as e:
         log.error("Error handling UI event", event)
         log.debug(e)
         log.debug_traceback()
         return False
Beispiel #13
0
    def call_remotely(self, rpcdata, response=True):
        from datetime import datetime

        r = Request("call", rpcdata)
        call_started = datetime.now()
        r.diagnostic["remote_call_start"] = str(call_started)
        if not response:
            r.request_id = None

        try:
            self.rpchost.put(r, self.peer_id)
        except Exception as e:
            if self.rpchost:
                log.debug("[call_remotely] Error in RPC operation:", e)
                log.debug_traceback()
            return None

        puttime = str(datetime.now())
        if response:
            self.rpchost.wait(r, timeout=10)
        call_complete = datetime.now()
        call_elapsed = call_complete - call_started
        r.diagnostic["remote_call_complete"] = call_complete
        r.diagnostic["remote_call_put"] = puttime

        callinfo = self.call_stats.setdefault(rpcdata.get('func'), {})
        total = callinfo.get("total")
        if total:
            total += call_elapsed
        else:
            total = call_elapsed
        callinfo["total"] = total
        count = callinfo.get("count", 0) + 1
        callinfo["count"] = count
        callinfo["avgtime"] = total / count


        if not response:
            return None
        elif not r.result:
            print "FIXME: no result should return a deferment"
            return None

        status, retval = r.result
        if status == RPCWrapper.METHOD_OK:
            return retval
        elif status == RPCWrapper.METHOD_FAILED:
            raise RPCWrapper.MethodFailed(False, retval)
Beispiel #14
0
    def _run_onload(self, objects):
        from .mfp_app import MFPApp
        for phase in (0,1):
            for obj in objects:
                try:
                    if obj.do_onload:
                        obj.onload(phase)
                except Exception as e:
                    log.error("Problem initializing %s.%s" % (obj.scope.name, obj.name))
                    log.debug_traceback()

        self.update_export_bounds()

        if MFPApp().gui_command:
            MFPApp().gui_command.load_complete()
        return True
Beispiel #15
0
    def _run_onload(self, objects):
        from .mfp_app import MFPApp
        for phase in (0,1):
            for obj in objects:
                try:
                    if obj.do_onload:
                        obj.onload(phase)
                except Exception as e:
                    log.error("Problem initializing %s.%s" % (obj.scope.name, obj.name))
                    log.debug_traceback()

        self.update_export_bounds()

        if MFPApp().gui_command:
            MFPApp().gui_command.load_complete()
        return True
Beispiel #16
0
 def grab_handler(stage, event):
     try:
         r = self.input_mgr.handle_event(stage, event)
         if not self.embed.has_focus():
             log.debug("event handler: do not have focus")
             if hasattr(event, 'keyval'):
                 log.debug("keyval was", event.keyval)
             else:
                 log.debug("event was:", event.type)
             self.grab_focus()
             return False
         return r
     except Exception as e:
         import traceback
         log.error("Error handling UI event", event)
         log.debug(e)
         log.debug_traceback()
         return False
Beispiel #17
0
 def grab_handler(stage, event):
     try:
         r = self.input_mgr.handle_event(stage, event)
         if not self.embed.has_focus():
             log.debug("event handler: do not have focus")
             if hasattr(event, 'keyval'):
                 log.debug("keyval was", event.keyval)
             else:
                 log.debug("event was:", event.type)
             self.grab_focus()
             return False
         return r
     except Exception, e:
         import traceback
         log.error("Error handling UI event", event)
         log.debug(e)
         log.debug_traceback()
         return False
Beispiel #18
0
    def _resize_cb(self, widget, rect):
        try:
            self.stage.set_size(rect.width, rect.height)
            if self.hud_mode_txt:
                self.hud_mode_txt.set_position(self.stage.get_width()-80,
                                               self.stage.get_height()-25)

            if self.hud_prompt:
                self.hud_prompt.set_position(10, self.stage.get_height() - 25)

            if self.hud_prompt_input:
                self.hud_prompt_input.set_position(15 + self.hud_prompt.get_width(),
                                                   self.stage.get_height() - 25)
        except Exception as e:
            log.error("Error handling UI event", event)
            log.debug(e)
            log.debug_traceback()

        return False
Beispiel #19
0
    def _resize_cb(self, widget, rect):
        try:
            self.stage.set_size(rect.width, rect.height)
            if self.hud_mode_txt:
                self.hud_mode_txt.set_position(self.stage.get_width() - 80,
                                               self.stage.get_height() - 25)

            if self.hud_prompt:
                self.hud_prompt.set_position(10, self.stage.get_height() - 25)

            if self.hud_prompt_input:
                self.hud_prompt_input.set_position(
                    15 + self.hud_prompt.get_width(),
                    self.stage.get_height() - 25)
        except Exception as e:
            log.error("Error handling UI event", event)
            log.debug(e)
            log.debug_traceback()

        return False
Beispiel #20
0
    def run(self):
        work = []
        retry = []

        while not self.join_req:
            with self.lock:
                self.cv.wait(0.25)
                work = []
                if self.queue:
                    work.extend(self.queue)
                    self.queue = []

                if self.failed:
                    toonew = []
                    newest = datetime.utcnow() - timedelta(milliseconds=250)
                    for jobs, timestamp in self.failed:
                        if timestamp < newest:
                            work.extend(jobs)
                        else:
                            toonew.append((jobs, timestamp))
                    self.failed = toonew
            retry = []
            for unit, retry_count, data in work:
                try:
                    done = unit(*data)
                except Exception as e:
                    log.debug("Exception while running", unit)
                    log.debug_traceback()

                if not done and retry_count:
                    if isinstance(retry_count, (int, float)):
                        if retry_count > 1:
                            retry_count -= 1
                        else:
                            log.warning("[TaskNibbler] ran out of retries for", unit, data)
                            retry_count = False
                    retry.append((unit, retry_count, data))

            if retry:
                with self.lock:
                    self.failed.append((retry, datetime.utcnow()))
Beispiel #21
0
    def run(self):
        work = []
        retry = []

        while not self.join_req:
            with self.lock:
                self.cv.wait(0.25)
                work = []
                if self.queue:
                    work.extend(self.queue)
                    self.queue = []

                if self.failed:
                    toonew = []
                    newest = datetime.utcnow() - timedelta(milliseconds=250)
                    for jobs, timestamp in self.failed:
                        if timestamp < newest:
                            work.extend(jobs)
                        else:
                            toonew.append((jobs, timestamp))
                    self.failed = toonew
            retry = []
            for unit, retry_count, data in work:
                try:
                    done = unit(*data)
                except Exception as e:
                    log.debug("Exception while running", unit)
                    log.debug_traceback()

                if not done and retry_count:
                    if isinstance(retry_count, (int, float)):
                        if retry_count > 1:
                            retry_count -= 1
                        else:
                            log.warning("[TaskNibbler] ran out of retries for", unit, data)
                            retry_count = False
                    retry.append((unit, retry_count, data))

            if retry:
                with self.lock:
                    self.failed.append((retry, datetime.utcnow()))
Beispiel #22
0
    def add_element(self, factory, x=None, y=None):
        if x is None:
            x = self.input_mgr.pointer_x
        if y is None:
            y = self.input_mgr.pointer_y

        try:
            b = factory(self, x, y)
        except Exception as e:
            import traceback
            log.warning("add_element: Error while creating with factory", factory)
            log.warning(e)
            log.debug_traceback()
            return True

        self.active_layer().add(b)
        self.register(b)
        self.refresh(b)
        self.select(b)

        b.begin_edit()
        return True
Beispiel #23
0
    def add_element(self, factory, x=None, y=None):
        if x is None:
            x = self.input_mgr.pointer_x
        if y is None:
            y = self.input_mgr.pointer_y

        try:
            b = factory(self, x, y)
        except Exception as e:
            import traceback
            log.warning("add_element: Error while creating with factory",
                        factory)
            log.warning(e)
            log.debug_traceback()
            return True

        self.active_layer().add(b)
        self.register(b)
        self.refresh(b)
        self.select(b)

        b.begin_edit()
        return True
Beispiel #24
0
    def handle_event(self, stage, event):
        from gi.repository import Clutter
        from mfp import log

        keysym = None
        if event.type in (
                Clutter.EventType.KEY_PRESS, Clutter.EventType.KEY_RELEASE,
                Clutter.EventType.BUTTON_PRESS,
                Clutter.EventType.BUTTON_RELEASE, Clutter.EventType.SCROLL):
            self.keyseq.process(event)
            if len(self.keyseq.sequences):
                keysym = self.keyseq.pop()
        elif event.type == Clutter.EventType.MOTION:
            # FIXME: if the scaling changes so that window.stage_pos would return a
            # different value, that should generate a MOTION event.  Currently we are
            # just kludging pointer_x and pointer_y from the scale callback.
            self.pointer_ev_x = event.x
            self.pointer_ev_y = event.y
            self.pointer_x, self.pointer_y = self.window.stage_pos(event.x, event.y)
            self.keyseq.process(event)
            if len(self.keyseq.sequences):
                keysym = self.keyseq.pop()

        elif event.type == Clutter.EventType.ENTER:
            src = self.event_sources.get(event.source)

            now = datetime.now()
            if (self.pointer_leave_time is not None
                and (now - self.pointer_leave_time) > timedelta(milliseconds=100)):
                self.keyseq.mod_keys = set()
                self.window.grab_focus()

            if src and self.window.object_visible(src):
                self.pointer_obj = src
                self.pointer_obj_time = now

        elif event.type == Clutter.EventType.LEAVE:
            src = self.event_sources.get(event.source)
            self.pointer_leave_time = datetime.now()
            if src == self.pointer_obj:
                self.pointer_lastobj = self.pointer_obj
                self.pointer_obj = None
                self.pointer_obj_time = None
        else:
            log.debug("event type not matched:", event.type)
            return False

        if not keysym:
            return True

        retry_count = 0
        while True:
            rv = None
            try:
                retry_count += 1
                rv = self.handle_keysym(keysym)
            except self.InputNeedsRequeue, e:
                if retry_count < 5:
                    continue
                else:
                    return False
            except Exception, e:
                log.error("Exception while handling key command", keysym)
                log.debug(e)
                log.debug_traceback()
Beispiel #25
0
 def handled(*args, **kwargs):
     try:
         return thunk(*args, **kwargs)
     except Exception as e:
         log.debug("Error in", thunk.__name__, e)
         log.debug_traceback()
Beispiel #26
0
    def run(self):
        '''
        RPCHost.run: perform IO on managed sockets, dispatch data
        '''
        self.read_workers.start()

        if RPCWrapper.rpchost is None:
            RPCWrapper.rpchost = self

        import select

        self.fdsockets = {}

        while not self.join_req:
            rdy = None
            for s in self.managed_sockets.values():
                if s.fileno() not in self.fdsockets:
                    self.fdsockets[s.fileno()] = s
            try:
                sockets = list(self.fdsockets.keys())
                if sockets:
                    rdy, _w, _x = select.select(list(self.fdsockets.keys()), [], [], 0.1)
                else:
                    time.sleep(0.1)
            except Exception as e:
                print("select exception:", e)

            if not rdy:
                continue
            syncbytes = 8
            sync = b''
            for rsock in rdy:
                jdata = b''
                retry = 1
                while retry:
                    sock = self.fdsockets.get(rsock)
                    if sock is None:
                        retry = 0
                        jdata = None
                        continue

                    try:
                        sync = sync[syncbytes:]
                        syncbit = sock.recv(syncbytes)
                        if not syncbit:
                            raise self.RecvError()
                        sync += syncbit
                        if sync != RPCHost.SYNC_MAGIC:
                            syncbytes = 1
                            retry = 1
                            raise self.SyncError()
                        else:
                            syncbytes = 8
                            retry = 0
                        jlen = sock.recv(8)
                        jlen = int(jlen)

                        recvlen = 0
                        while recvlen < jlen:
                            jdata += sock.recv(jlen-recvlen)
                            recvlen = len(jdata)
                            if recvlen < jlen:
                                log.warning("RPCHost: got short packet (%d of %d)"
                                            % (recvlen, jlen))
                    except RPCHost.SyncError as e:
                        log.warning("RPCHost: sync error, resyncing")
                        pass
                    except (socket.error, RPCHost.RecvError) as e:
                        log.warning("RPCHost: communication error")
                        retry = 0
                        jdata = None
                        deadpeer = self.peers_by_socket[sock]
                        self.unmanage(deadpeer)
                    except Exception as e:
                        log.error("RPCHost: unhandled exception", type(e), e)
                        log.debug(jdata)
                        log.debug_traceback()
                        retry = 0
                        jdata = b""

                    if jdata is not None and len(jdata) >=  jlen:
                        peer_id = self.peers_by_socket.get(sock)
                        self.read_workers.submit((jdata, peer_id))

        if self.node_id == 0:
            peers = list(self.managed_sockets.keys())
            for node in peers:
                req = Request("exit_request", {})
                self.put(req, node)
                self.wait(req)
                del self.managed_sockets[node]

        elif 0 in self.managed_sockets:
            req = Request("exit_notify", {})
            self.put(req, 0)
            self.wait(req)


        for clsname, cls in list(self.served_classes.items()):
            self.unpublish(cls)

        for clsname, cls in RPCWrapper.rpctype.items():
            cls.publishers = []

        if RPCWrapper.rpchost == self:
            RPCWrapper.rpchost = None
        self.read_workers.finish()
Beispiel #27
0
    def handle_event(self, stage, event):
        from gi.repository import Clutter
        from mfp import log

        keysym = None
        if event.type in (Clutter.EventType.KEY_PRESS,
                          Clutter.EventType.KEY_RELEASE,
                          Clutter.EventType.BUTTON_PRESS,
                          Clutter.EventType.BUTTON_RELEASE,
                          Clutter.EventType.SCROLL):
            self.keyseq.process(event)
            if len(self.keyseq.sequences):
                keysym = self.keyseq.pop()
        elif event.type == Clutter.EventType.MOTION:
            # FIXME: if the scaling changes so that window.stage_pos would return a
            # different value, that should generate a MOTION event.  Currently we are
            # just kludging pointer_x and pointer_y from the scale callback.
            self.pointer_ev_x = event.x
            self.pointer_ev_y = event.y
            self.pointer_x, self.pointer_y = self.window.stage_pos(
                event.x, event.y)
            self.keyseq.process(event)
            if len(self.keyseq.sequences):
                keysym = self.keyseq.pop()

        elif event.type == Clutter.EventType.ENTER:
            src = self.event_sources.get(event.source)

            now = datetime.now()
            if (self.pointer_leave_time is not None and
                (now - self.pointer_leave_time) > timedelta(milliseconds=100)):
                self.keyseq.mod_keys = set()
                self.window.grab_focus()

            if src and self.window.object_visible(src):
                self.pointer_obj = src
                self.pointer_obj_time = now

        elif event.type == Clutter.EventType.LEAVE:
            src = self.event_sources.get(event.source)
            self.pointer_leave_time = datetime.now()
            if src == self.pointer_obj:
                self.pointer_lastobj = self.pointer_obj
                self.pointer_obj = None
                self.pointer_obj_time = None
        else:
            log.debug("event type not matched:", event.type)
            return False

        if not keysym:
            return True

        retry_count = 0
        while True:
            rv = None
            try:
                retry_count += 1
                rv = self.handle_keysym(keysym)
            except self.InputNeedsRequeue as e:
                if retry_count < 5:
                    continue
                else:
                    return False
            except Exception as e:
                log.error("Exception while handling key command", keysym)
                log.debug(e)
                log.debug_traceback()
            return rv
Beispiel #28
0
    def run(self):
        '''
        RPCHost.run: perform IO on managed sockets, dispatch data
        '''
        self.read_workers.start()

        if RPCWrapper.rpchost is None:
            RPCWrapper.rpchost = self

        import select

        self.fdsockets = {}

        while not self.join_req:
            rdy = None
            for s in self.managed_sockets.values():
                if s.fileno() not in self.fdsockets:
                    self.fdsockets[s.fileno()] = s
            try:
                sockets = self.fdsockets.keys()
                if sockets:
                    rdy, _w, _x = select.select(self.fdsockets.keys(), [], [], 0.1)
                else:
                    time.sleep(0.1)
            except Exception, e:
                print "select exception:", e

            if not rdy:
                continue
            syncbytes = 8
            sync = ''
            for rsock in rdy:
                jdata = ''
                retry = 1
                while retry:
                    sock = self.fdsockets.get(rsock)
                    if sock is None:
                        retry = 0
                        jdata = None
                        continue

                    try:
                        sync = sync[syncbytes:]
                        syncbit = sock.recv(syncbytes)
                        if not syncbit:
                            raise self.RecvError()
                        sync += syncbit
                        if sync != RPCHost.SYNC_MAGIC:
                            syncbytes = 1
                            retry = 1
                            raise self.SyncError()
                        else:
                            syncbytes = 8
                            retry = 0
                        jlen = sock.recv(8)
                        jlen = int(jlen)

                        recvlen = 0
                        while recvlen < jlen:
                            jdata += sock.recv(jlen-recvlen)
                            recvlen = len(jdata)
                            if recvlen < jlen:
                                log.warning("RPCHost: got short packet (%d of %d)"
                                            % (recvlen, jlen))
                    except RPCHost.SyncError, e:
                        log.warning("RPCHost: sync error, resyncing")
                        pass
                    except (socket.error, RPCHost.RecvError) as e:
                        log.warning("RPCHost: communication error")
                        retry = 0
                        jdata = None
                        deadpeer = self.peers_by_socket[sock]
                        self.unmanage(deadpeer)
                    except Exception, e:
                        log.error("RPCHost: unhandled exception", type(e), e)
                        log.debug(jdata)
                        log.debug_traceback()
                        retry = 0
                        jdata = ""
Beispiel #29
0
    def run(self):
        '''
        RPCHost.run: perform IO on managed sockets, dispatch data
        '''
        self.read_workers.start()

        if RPCWrapper.rpchost is None:
            RPCWrapper.rpchost = self

        import select

        self.fdsockets = {}

        while not self.join_req:
            rdy = None
            for s in self.managed_sockets.values():
                if s.fileno() not in self.fdsockets:
                    self.fdsockets[s.fileno()] = s
            try:
                sockets = list(self.fdsockets.keys())
                if sockets:
                    rdy, _w, _x = select.select(list(self.fdsockets.keys()),
                                                [], [], 0.1)
                else:
                    time.sleep(0.1)
            except Exception as e:
                print("select exception:", e)

            if not rdy:
                continue
            syncbytes = 8
            sync = b''
            for rsock in rdy:
                jdata = b''
                retry = 1
                while retry:
                    sock = self.fdsockets.get(rsock)
                    if sock is None:
                        retry = 0
                        jdata = None
                        continue

                    try:
                        sync = sync[syncbytes:]
                        syncbit = sock.recv(syncbytes)
                        if not syncbit:
                            raise self.RecvError()
                        sync += syncbit
                        if sync != RPCHost.SYNC_MAGIC:
                            syncbytes = 1
                            retry = 1
                            raise self.SyncError()
                        else:
                            syncbytes = 8
                            retry = 0
                        jlen = sock.recv(8)
                        jlen = int(jlen)

                        recvlen = 0
                        while recvlen < jlen:
                            jdata += sock.recv(jlen - recvlen)
                            recvlen = len(jdata)
                            if recvlen < jlen:
                                log.warning(
                                    "RPCHost: got short packet (%d of %d)" %
                                    (recvlen, jlen))
                    except RPCHost.SyncError as e:
                        log.warning("RPCHost: sync error, resyncing")
                        pass
                    except (socket.error, RPCHost.RecvError) as e:
                        log.warning("RPCHost: communication error")
                        retry = 0
                        jdata = None
                        deadpeer = self.peers_by_socket[sock]
                        self.unmanage(deadpeer)
                    except Exception as e:
                        log.error("RPCHost: unhandled exception", type(e), e)
                        log.debug(jdata)
                        log.debug_traceback()
                        retry = 0
                        jdata = b""

                    if jdata is not None and len(jdata) >= jlen:
                        peer_id = self.peers_by_socket.get(sock)
                        self.read_workers.submit((jdata, peer_id))

        if self.node_id == 0:
            peers = list(self.managed_sockets.keys())
            for node in peers:
                req = Request("exit_request", {})
                self.put(req, node)
                self.wait(req)
                del self.managed_sockets[node]

        elif 0 in self.managed_sockets:
            req = Request("exit_notify", {})
            self.put(req, 0)
            self.wait(req)

        for clsname, cls in list(self.served_classes.items()):
            self.unpublish(cls)

        for clsname, cls in RPCWrapper.rpctype.items():
            cls.publishers = []

        if RPCWrapper.rpchost == self:
            RPCWrapper.rpchost = None
        self.read_workers.finish()