Exemple #1
0
    def publish (self, topic, *args, **kwargs):

        if topic not in self.handlers:
            return True

        excluded = []

        for handler in self.handlers[topic]:

            # FIXME: reuse connections? if not, TIME_WAIT sockets start to slow down things
            proxy = Proxy (uri=handler["proxy"])

            try:
                dispatcher = getattr(proxy, handler["method"])
                #proxy._setOneway ([handler["method"]]) should be faster but results say no!
                dispatcher (*args, **kwargs)
            except AttributeError, e:
                tb_size = len(traceback.extract_tb(sys.exc_info()[2]))
                if tb_size == 1:
                    log.debug("Invalid proxy method ('%s %s') for '%s' handler." % \
                              (handler["proxy"], handler["method"], topic))
                else:
                    log.debug ("Handler (%s) raised an exception. Removing from subscribers list." % proxy)
                    log.exception(e)

                excluded.append(handler)
                continue
            except Pyro.errors.ProtocolError, e:
                log.debug ("Unreachable handler (%s). Removing from subscribers list." % proxy)
                excluded.append(handler)
                continue
Exemple #2
0
    def __do(self, other, action):

        handler = {
            "topic": self.method,
            "handler": {
                "proxy": "",
                "method": ""
            }
        }

        # REMEBER: Return a copy of this wrapper as we are using +=

        # Can't add itself as a subscriber
        if other == self:
            return self

        # passing a proxy method?
        if not isinstance(other, ProxyMethod):
            log.debug("Invalid parameter: %s" % other)
            raise TypeError("Invalid parameter: %s" % other)

        handler["handler"]["proxy"] = other.proxy.URI
        handler["handler"]["method"] = str(other.__name__)

        try:
            self.sender("%s.%s" % (EVENTS_PROXY_NAME, action), (handler, ), {})
        except Exception, e:
            log.exception("Cannot %s to topic '%s' using proxy '%s'." %
                          (action, self.method, self.proxy))
Exemple #3
0
    def __do (self, other, action):

        handler = {"topic"    : self.method,
                   "handler"  : {"proxy" : "",
                                "method": ""}
                   }

        # REMEBER: Return a copy of this wrapper as we are using +=
        
        # Can't add itself as a subscriber
        if other == self:
            return self
        
        # passing a proxy method?
        if not isinstance (other, ProxyMethod):
            log.debug("Invalid parameter: %s" % other)
            raise TypeError("Invalid parameter: %s" % other)

        handler["handler"]["proxy"] = other.proxy.URI
        handler["handler"]["method"] = str(other.__name__)
   
        try:
            self.sender ("%s.%s" % (EVENTS_PROXY_NAME, action), (handler,), {})
        except Exception, e:
            log.exception("Cannot %s to topic '%s' using proxy '%s'." % (action,
                                                                         self.method,
                                                                         self.proxy))
Exemple #4
0
    def addClass(self, cls, name, config={}, start=True):
        """
        Add the class 'cls' to the system configuring it using 'config'.

        @param cls: The class to add to the system.
        @type cls: ChimeraObject

        @param name: The name of the new class instance.
        @type name: str

        @param config: The configuration dictionary for the object.
        @type config: dict

        @param start: start the object after initialization.
        @type start: bool

        @raises ChimeraObjectException: Internal error on managed (user) object.
        @raises NotValidChimeraObjectException: When a object which doesn't inherites from ChimeraObject is given in location.
        @raises InvalidLocationException: When the requested location s invalid.              

        @return: retuns a proxy for the object if sucessuful, False otherwise.
        @rtype: Proxy or bool
        """

        location = Location(cls=cls.__name__, name=name, config=config)

        # names must not start with a digit
        if location.name[0] in "0123456789":
            raise InvalidLocationException(
                "Invalid instance name: %s (must start with a letter)" %
                location)

        if location in self.resources:
            raise InvalidLocationException(
                "Location %s is already in the system. Only one allowed (Tip: change the name!)."
                % location)

        # check if it's a valid ChimeraObject
        if not issubclass(cls, ChimeraObject):
            raise NotValidChimeraObjectException(
                "Cannot add the class %s. It doesn't descend from ChimeraObject."
                % cls.__name__)

        # run object __init__ and configure using location configuration
        # it runs on the same thread, so be a good boy
        # and don't block manager's thread
        try:
            obj = cls()
        except Exception:
            log.exception("Error in %s __init__." % location)
            raise ChimeraObjectException("Error in %s __init__." % location)

        try:
            for k, v in location.config.items():
                obj[k] = v
        except (OptionConversionException, KeyError), e:
            log.exception("Error configuring %s." % location)
            raise ChimeraObjectException("Error configuring %s. (%s)" %
                                         (location, e))
    def addClass(self, cls, name, config={}, start=True):
        """
        Add the class 'cls' to the system configuring it using 'config'.

        @param cls: The class to add to the system.
        @type cls: ChimeraObject

        @param name: The name of the new class instance.
        @type name: str

        @param config: The configuration dictionary for the object.
        @type config: dict

        @param start: start the object after initialization.
        @type start: bool

        @raises ChimeraObjectException: Internal error on managed (user) object.
        @raises NotValidChimeraObjectException: When a object which doesn't inherites from ChimeraObject is given in location.
        @raises InvalidLocationException: When the requested location s invalid.              

        @return: retuns a proxy for the object if sucessuful, False otherwise.
        @rtype: Proxy or bool
        """

        location = Location(cls=cls.__name__, name=name, config=config)

        # names must not start with a digit
        if location.name[0] in "0123456789":
            raise InvalidLocationException("Invalid instance name: %s (must start with a letter)" % location)

        if location in self.resources:
            raise InvalidLocationException(
                "Location %s is already in the system. Only one allowed (Tip: change the name!)." % location
            )

        # check if it's a valid ChimeraObject
        if not issubclass(cls, ChimeraObject):
            raise NotValidChimeraObjectException(
                "Cannot add the class %s. It doesn't descend from ChimeraObject." % cls.__name__
            )

        # run object __init__ and configure using location configuration
        # it runs on the same thread, so be a good boy
        # and don't block manager's thread
        try:
            obj = cls()
        except Exception:
            log.exception("Error in %s __init__." % location)
            raise ChimeraObjectException("Error in %s __init__." % location)

        try:
            for k, v in location.config.items():
                obj[k] = v
        except (OptionConversionException, KeyError), e:
            log.exception("Error configuring %s." % location)
            raise ChimeraObjectException("Error configuring %s. (%s)" % (location, e))
Exemple #6
0
    def done (self, task, error=None):

        if error:
            log.debug("Error processing program %s." % str(task))
            log.exception(error)
        else:
            task.finished = True
        
        self.rq.task_done()
        self.machine.wakeup()
    def done(self, task, error=None):

        if error:
            log.debug("Error processing program %s." % str(task))
            log.exception(error)
        else:
            task.finished = True

        self.rq.task_done()
        self.machine.wakeup()
Exemple #8
0
    def test_expose (self):

        cam = self.manager.getProxy(self.CAMERA)

        frames = 0

        try:
            frames = cam.expose(exptime=2, frames=2, interval=0.5, filename="autogen-expose.fits")
        except Exception, e:
            log.exception("problems")
    def _getHeaders (self, manager, locations):

        for location in locations:

            if not location in self._proxies:
                try:
                    self._proxies[location] = manager.getProxy(location)
                except Exception, e:
                    log.exception('Unable to get metadata from %s' % (location))

            self.headers += self._proxies[location].getMetadata(self)
Exemple #10
0
    def _getHeaders(self, manager, locations):

        for location in locations:

            if not location in self._proxies:
                try:
                    self._proxies[location] = manager.getProxy(location)
                except Exception, e:
                    log.exception('Unable to get metadata from %s' %
                                  (location))

            self.headers += self._proxies[location].getMetadata(self)
Exemple #11
0
    def start(self, location):
        """
        Start the object pointed by 'location'.

        @param location: The object to start.
        @type location: Location or str

        @raises ObjectNotFoundException: When te request object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.
        
        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException("Location %s was not found." %
                                          location)

        log.info("Starting %s." % location)

        resource = self.resources.get(location)

        if resource.instance.getState() == State.RUNNING:
            return True

        try:
            resource.instance.__start__()
        except Exception:
            log.exception("Error running %s __start__ method." % location)
            raise ChimeraObjectException("Error running %s __start__ method." %
                                         location)

        try:
            # FIXME: thread exception handling
            # ok, now schedule object main in a new thread
            log.info("Running %s. __main___." % location)

            loop = threading.Thread(target=resource.instance.__main__)
            loop.setName(str(resource.location) + ".__main__")
            loop.setDaemon(True)
            loop.start()

            resource.instance.__setstate__(State.RUNNING)
            resource.created = time.time()
            resource.loop = loop

            return True

        except Exception, e:
            log.exception("Error running %s __main__ method." % location)
            resource.instance.__setstate__(State.STOPPED)
            raise ChimeraObjectException("Error running %s __main__ method." %
                                         location)
    def test_expose(self):

        cam = self.manager.getProxy(Camera)

        frames = 0

        try:
            frames = cam.expose(exptime=2,
                                frames=2,
                                interval=0.5,
                                filename="autogen-expose.fits")
        except Exception, e:
            log.exception("problems")
Exemple #13
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")
            
        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError), e:
            log.exception(e)
            log.error("There was a problem reading your configuration file. (%s)" % e)
            sys.exit(1)
Exemple #14
0
    def start (self, location):
        """
        Start the object pointed by 'location'.

        @param location: The object to start.
        @type location: Location or str

        @raises ObjectNotFoundException: When te request object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.
        
        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException ("Location %s was not found." % location)
            
        log.info("Starting %s." % location)            

        resource = self.resources.get(location)

        if resource.instance.getState() == State.RUNNING:
            return True

        try:
            resource.instance.__start__()
        except Exception:
            log.exception ("Error running %s __start__ method." % location)
            raise ChimeraObjectException("Error running %s __start__ method." % location)

        try:
            # FIXME: thread exception handling
            # ok, now schedule object main in a new thread
            log.info("Running %s. __main___." % location)                        

            loop = threading.Thread(target=resource.instance.__main__)
            loop.setName(str(resource.location) + ".__main__")
            loop.setDaemon(True)
            loop.start()

            resource.instance.__setstate__(State.RUNNING)
            resource.created = time.time()
            resource.loop = loop

            return True

        except Exception, e:
            log.exception("Error running %s __main__ method." % location)
            resource.instance.__setstate__(State.STOPPED)
            raise ChimeraObjectException("Error running %s __main__ method." % location)
Exemple #15
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError), e:
            log.exception(e)
            log.error(
                "There was a problem reading your configuration file. (%s)" %
                e)
            sys.exit(1)
Exemple #16
0
    def stop(self, location):
        """
        Stop the object pointed by 'location'.

        @param location: The object to stop.
        @type location: Location or str

        @raises ObjectNotFoundException: When the requested object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.

        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """

        if location not in self.resources:
            raise ObjectNotFoundException("Location %s was not found." %
                                          location)

        log.info("Stopping %s." % location)

        resource = self.resources.get(location)

        try:

            # stop control loop
            if resource.loop and resource.loop.isAlive():
                resource.instance.__abort_loop__()
                try:
                    resource.loop.join()
                except KeyboardInterrupt:
                    # ignore Ctrl+C on shutdown
                    pass

            if resource.instance.getState() != State.STOPPED:
                resource.instance.__stop__()
                resource.instance.__setstate__(State.STOPPED)

            return True

        except Exception, e:
            log.exception(
                "Error running %s __stop__ method. Exception follows..." %
                location)
            raise ChimeraObjectException("Error running %s __stop__ method." %
                                         location)
Exemple #17
0
    def test_set_info (self):

        m = self.m

        try:
            m.setLat("-22 32 03")
            m.setLong("-45 34 57")
            m.setDate(time.time())
            m.setLocalTime(time.time())
            m.setUTCOffset(3)

            m.setLat(Coord.fromDMS("-22 32 03"))
            m.setLong(Coord.fromDMS("-45 34 57"))
            m.setDate(dt.date.today())
            m.setLocalTime(dt.datetime.now().time())
            m.setUTCOffset(3)
        except Exception:
            log.exception("error")
Exemple #18
0
    def test_expose(self):

        cam = self.manager.getProxy(self.CAMERA)

        frames = 0

        try:
            frames = cam.expose(exptime=2,
                                frames=2,
                                interval=0.5,
                                filename="autogen-expose.fits")
        except Exception as e:
            log.exception("problems")

        assert len(frames) == 2
        assert isinstance(frames[0], Proxy)
        assert isinstance(frames[1], Proxy)

        self.assertEvents(CameraStatus.OK, CameraStatus.OK)
Exemple #19
0
    def stop (self, location):
        """
        Stop the object pointed by 'location'.

        @param location: The object to stop.
        @type location: Location or str

        @raises ObjectNotFoundException: When the requested object or the Manager was not found.
        @raises ChimeraObjectException: Internal error on managed (user) object.

        @return: retuns True if sucessfull. False otherwise.
        @rtype: bool
        """
    
        if location not in self.resources:
            raise ObjectNotFoundException ("Location %s was not found." % location)

        log.info("Stopping %s." % location)
            
        resource = self.resources.get(location)

        try:

            # stop control loop
            if resource.loop and resource.loop.isAlive():
                resource.instance.__abort_loop__()
                try:
                    resource.loop.join()
                except KeyboardInterrupt:
                    # ignore Ctrl+C on shutdown
                    pass

            if resource.instance.getState() != State.STOPPED:
                resource.instance.__stop__ ()
                resource.instance.__setstate__(State.STOPPED)

            return True

        except Exception, e:
            log.exception("Error running %s __stop__ method. Exception follows..." % location)
            raise ChimeraObjectException("Error running %s __stop__ method." % location)
Exemple #20
0
    def test_log (self):

        class Simple (ChimeraObject):
            def __init__ (self):
                ChimeraObject.__init__(self)

            def answer (self):
                try:
                    raise ChimeraException("I'm an Exception, sorry.")
                except ChimeraException:
                    self.log.exception("from except: wow, exception caught.")
                    raise ChimeraException("I'm a new Exception, sorry again")

        manager = Manager()
        manager.addClass(Simple, "simple")

        simple = manager.getProxy(Simple)

        try:
            simple.answer()
        except ChimeraException, e:
            assert e.cause != None
            log.exception("wow, something wrong")
Exemple #21
0
    def startup(self):

        if self.options.daemon:
            # detach
            log.info("FIXME: Daemon...")

        # system config
        try:
            self.config = SystemConfig.fromFile(self.options.config_file)
        except (InvalidLocationException, IOError) as e:
            log.exception(e)
            log.error(
                "There was a problem reading your configuration file. (%s)" %
                e)
            sys.exit(1)

        # manager
        if not self.options.dry:
            log.info("Starting system.")
            log.info("Chimera: %s" % _chimera_version_)
            log.info("Chimera prefix: %s" % ChimeraPath().root())
            log.info("Python: %s" % platform.python_version())
            log.info("System: %s" % ' '.join(platform.uname()))

            try:
                self.manager = Manager(**self.config.chimera)
            except ChimeraException as e:
                log.error(
                    "Chimera is already running on this machine. Use chimera-admin to manage it."
                )
                sys.exit(1)

            log.info("Chimera: running on " + self.manager.getHostname() +
                     ":" + str(self.manager.getPort()))
            log.info("Chimera: reading configuration from %s" %
                     os.path.realpath(self.options.config_file))

        # add site object
        if not self.options.dry:

            for site in self.config.sites:
                self.manager.addClass(Site, site.name, site.config, True)

        # search paths
        log.info(
            "Setting objects include path from command line parameters...")
        for _dir in self.options.inst_dir:
            self.paths["instruments"].append(_dir)

        for _dir in self.options.ctrl_dir:
            self.paths["controllers"].append(_dir)

        # init from config
        log.info("Trying to start instruments...")
        for inst in self.config.instruments + self.options.instruments:

            if self.options.dry:
                print(inst)
            else:
                self._add(inst, path=self.paths["instruments"], start=True)

        log.info("Trying to start controllers...")
        for ctrl in self.config.controllers + self.options.controllers:

            if self.options.dry:
                print(ctrl)
            else:
                self._add(ctrl, path=self.paths["controllers"], start=True)

        log.info("System up and running.")

        # ok, let's wait manager work
        if self.wait and not self.options.dry:
            self.manager.wait()
class EventsProxy:
    def __init__(self):
        self.handlers = {}

    def subscribe(self, handler):

        topic = handler["topic"]

        if topic not in self.handlers:
            self.handlers[topic] = []

        if handler["handler"] not in self.handlers[topic]:
            self.handlers[topic].append(handler["handler"])

        return True

    def unsubscribe(self, handler):

        topic = handler["topic"]

        if not topic in self.handlers:
            return True

        if handler["handler"] not in self.handlers[topic]:
            return True

        self.handlers[topic].remove(handler["handler"])

        return True

    def publish(self, topic, *args, **kwargs):

        if topic not in self.handlers:
            return True

        excluded = []

        for handler in self.handlers[topic]:

            # FIXME: reuse connections? if not, TIME_WAIT sockets start to slow down things
            proxy = Proxy(uri=handler["proxy"])

            try:
                dispatcher = getattr(proxy, handler["method"])
                #proxy._setOneway ([handler["method"]]) should be faster but results say no!
                dispatcher(*args, **kwargs)
            except AttributeError, e:
                log.debug("Invalid proxy method ('%s %s') for '%s' handler." % \
                          (handler["proxy"], handler["method"], topic))
                excluded.append(handler)
                continue
            except Pyro.errors.ProtocolError, e:
                log.debug(
                    "Unreachable handler (%s). Removing from subscribers list."
                    % proxy)
                excluded.append(handler)
                continue
            except Exception, e:
                log.debug(
                    "Handler (%s) raised an exception. Removing from subscribers list."
                    % proxy)
                log.exception(e)
                excluded.append(handler)
                continue