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
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))
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))
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))
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()
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)
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)
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")
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)
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 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)
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)
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")
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)
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)
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")
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