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
def next(self): if not self.rq.empty(): log.debug("bbbbbbbbbbbbbbbbbbbb self.rq %s", self.rq) print self.rq return self.rq.get() return None
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 _process(self, program): def process(): # session to be used by executor and handlers session = Session() task = session.merge(program) log.debug("[start] %s" % str(task)) self.controller.programBegin(program) try: self.executor.execute(task) log.debug("[finish] %s" % str(task)) self.scheduler.done(task) self.controller.programComplete(program, SchedulerStatus.OK) self.state(State.IDLE) except ProgramExecutionException, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ERROR, str(e)) self.state(State.IDLE) log.debug("[error] %s (%s)" % (str(task), str(e))) except ProgramExecutionAborted, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ABORTED, "Aborted by user.") self.state(State.OFF) log.debug("[aborted by user] %s" % str(task))
def _process(self, program): def process (): # session to be used by executor and handlers session = Session() task = session.merge(program) log.debug("[start] %s" % str(task)) self.controller.programBegin(program) try: self.executor.execute(task) log.debug("[finish] %s" % str(task)) self.scheduler.done(task) self.controller.programComplete(program, SchedulerStatus.OK) self.state(State.IDLE) except ProgramExecutionException, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ERROR, str(e)) self.state(State.IDLE) log.debug("[error] %s (%s)" % (str(task), str(e))) except ProgramExecutionAborted, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ABORTED, "Aborted by user.") self.state(State.OFF) log.debug("[aborted by user] %s" % str(task))
def execute(self, program): self.mustStop.clear() for action in program.actions: # aborted? if self.mustStop.isSet(): raise ProgramExecutionAborted() t0 = time.time() try: self.currentAction = action self.currentHandler = self.actionHandlers[type(action)] logMsg = str(self.currentHandler.log(action)) log.debug("[start] %s " % logMsg) self.controller.actionBegin(action, logMsg) self.currentHandler.process(action) # instruments just returns in case of abort, so we need to check handler # returned 'cause of abort or not if self.mustStop.isSet(): self.controller.actionComplete(action, SchedulerStatus.ABORTED) raise ProgramExecutionAborted() else: self.controller.actionComplete(action, SchedulerStatus.OK) except ProgramExecutionException, e: self.controller.actionComplete(action, SchedulerStatus.ERROR) raise except KeyError: log.debug("No handler to %s action. Skipping it" % action)
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 setJD(self,jd=None): ''' Configure time domain by specifing a julian day. It will use information on exposure time to build time bins that will be filled when selecting targets. ''' if not jd: site = Site() jd = np.floor(site.JD())+0.5 nightstart = _skysub.jd_sun_alt(self.sunMaxAlt, jd, self.sitelat, self.sitelong) nightend = _skysub.jd_sun_alt(self.sunMaxAlt, jd+0.5, self.sitelat, self.sitelong) log.debug('Nigh Start @JD= %.3f # Night End @JD = %.3f'%(nightstart,nightend)) tbin = np.max([np.max(self.sciExpTime),np.max(self.stdExpTime)])*self.nfilters/60./60./24. self.obsTimeBins = np.arange(nightstart,nightend+tbin,tbin) self.obsTimeMask = np.zeros(len(self.obsTimeBins)) self.obsTimeMask[-1] = 1.0 # Marking filled bins session = Session() scheduled = session.query(Program) for target in scheduled: tindex = np.abs(self.obsTimeBins - 2400000.5 - target.slewAt).argmin() self.obsTimeMask[tindex] = 1.0 self.isJD = True
def set (self, value): try: oldvalue = self._value self._value = self._checker.check(value, self._system, self._epoch) return oldvalue except OptionConversionException, e: log.debug ("Error setting %s: %s." % (self._name, str (e))) raise e
def process(): try: self.controller.process(exp) #FIXME: We should only set done with exposure upon some callback from the imagesave routine log.debug("Done with exposure: " + exp.__str__()) self.scheduler.done(exp) finally: self.state(State.IDLE)
def set(self, value): try: oldvalue = self._value self._value = self._checker.check(value, self._system, self._epoch) return oldvalue except OptionConversionException, e: log.debug("Error setting %s: %s." % (self._name, str(e))) raise e
def state(self, state=None): self.__stateLock.acquire() try: if not state: return self.__state log.debug("Chaning state, from %s to %s." % (self.__state, state)) self.__state = state self.wakeup() finally: self.__stateLock.release()
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 state(self, state=None): self.__stateLock.acquire() try: if not state: return self.__state if state == self.__state: return self.controller.stateChanged(state, self.__state) log.debug("Changing state, from %s to %s." % (self.__state, state)) self.__state = state self.wakeup() finally: self.__stateLock.release()
def beginExposure (self, manager): self._fetchPreHeaders(manager) if self["wait_dome"]: try: dome = manager.getProxy("/Dome/0") dome.syncWithTel() log.debug("Dome slit position synchronized with telescope position.") except ObjectNotFoundException: log.info("No dome present, taking exposure without dome sync.")
def beginExposure(self, manager): self._fetchPreHeaders(manager) if self["wait_dome"]: try: dome = manager.getProxy("/Dome/0") dome.syncWithTel() log.debug( "Dome slit position synchronized with telescope position.") except ObjectNotFoundException: log.info("No dome present, taking exposure without dome sync.")
def selectScienceTargets(self): ''' Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day. ''' session = Session() # [To be done] Reject objects that are close to the moon for tbin, time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # Select objects from database that where not observed and where not scheduled yet # In the future may include targets that where observed a number of nights ago. # This is still incomplete. We should also consider the distance from the previous pointing to the next! # Since a target can have a higher airmass but be farther away from a neaby target that will take less time # to point. # one way of selecting targets that are close together and have good airmass is to select regions that are close # to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions # to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky. targets = session.query(Targets).filter( Targets.observed == False).filter( Targets.scheduled == False).filter( Targets.type == self.sciFlag) lst = _skysub.lst(time, self.sitelong) #*360./24. alt = np.array([ _skysub.altit(target.targetDec, lst - target.targetRa, self.sitelat)[0] for target in targets ]) stg = alt.argmax() log.info('Selecting %s' % (targets[stg])) # Marking target as schedule tst = session.query(Targets).filter( Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() self.addObservation(t, time) self.obsTimeMask[tbin] = 1.0 else: log.debug( 'Bin %3i @mjd=%.3f already filled up with observations. Skipping...' % (tbin, time - 2400000.5)) #print i return 0 #targets
def _process(self, exp): log.debug("Starting to process exposure: " + exp.__str__()) def process(): try: self.controller.process(exp) #FIXME: We should only set done with exposure upon some callback from the imagesave routine log.debug("Done with exposure: " + exp.__str__()) self.scheduler.done(exp) finally: self.state(State.IDLE) t = threading.Thread(target=process) t.setDaemon(False) t.start()
def reschedule(self, machine): self.machine = machine self.rq = Queue(-1) session = Session() programs = session.query(Program).order_by(desc(Program.priority)).filter(Program.finished == False).all() if not programs: return log.debug("rescheduling, found %d runnable programs" % len(list(programs))) for program in programs: self.rq.put(program) machine.wakeup()
def reschedule (self, machine): self.machine = machine self.rq = Queue(-1) session = Session() programs = session.query(Program).order_by(desc(Program.priority)).filter(Program.finished == False).all() if not programs: return log.debug("rescheduling, found %d runnable programs" % len(list(programs))) for program in programs: self.rq.put(program) machine.wakeup()
def run(self): """ Until told to quit, retrieve the next task and execute it, calling the callback if any. """ while self.__isDying == False: cmd, args, kwargs, callback = self.__pool.getNextTask() # If there's nothing to do, just sleep a bit if cmd is None: sleep(ThreadPoolThread.threadSleepTime) else: log.debug("Running %s on thread %s" % (cmd, self.getName())) if callback is None: cmd(*args, **kwargs) else: callback(cmd(*args, **kwargs))
def _process(self, program): def process (): # session to be used by executor and handlers session = Session() task = session.merge(program) log.debug("[start] %s" % str(task)) site=Site() nowmjd=site.MJD() log.debug("[start] Current MJD is %f",nowmjd) if program.slewAt: waittime=(program.slewAt-nowmjd)*86.4e3 if waittime>0.0: log.debug("[start] Waiting until MJD %f to start slewing",program.slewAt) log.debug("[start] Will wait for %f seconds",waittime) time.sleep(waittime) else: log.debug("[start] Specified slew start MJD %s has already passed; proceeding without waiting",program.slewAt) else: log.debug("[start] No slew time specified, so no waiting") log.debug("[start] Current MJD is %f",site.MJD()) log.debug("[start] Proceeding since MJD %f should have passed",program.slewAt) self.controller.programBegin(program) try: self.executor.execute(task) log.debug("[finish] %s" % str(task)) self.scheduler.done(task) self.controller.programComplete(program, SchedulerStatus.OK) self.state(State.IDLE) except ProgramExecutionException, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ERROR, str(e)) self.state(State.IDLE) log.debug("[error] %s (%s)" % (str(task), str(e))) except ProgramExecutionAborted, e: self.scheduler.done(task, error=e) self.controller.programComplete(program, SchedulerStatus.ABORTED, "Aborted by user.") self.state(State.OFF) log.debug("[aborted by user] %s" % str(task))
def selectScienceTargets(self): ''' Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day. ''' session = Session() # [To be done] Reject objects that are close to the moon for tbin,time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # Select objects from database that where not observed and where not scheduled yet # In the future may include targets that where observed a number of nights ago. # This is still incomplete. We should also consider the distance from the previous pointing to the next! # Since a target can have a higher airmass but be farther away from a neaby target that will take less time # to point. # one way of selecting targets that are close together and have good airmass is to select regions that are close # to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions # to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky. targets = session.query(Targets).filter(Targets.observed == False).filter(Targets.scheduled == False).filter(Targets.type == self.sciFlag) lst = _skysub.lst(time,self.sitelong) #*360./24. alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0] for target in targets]) stg = alt.argmax() log.info('Selecting %s'%(targets[stg])) # Marking target as schedule tst = session.query(Targets).filter(Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() self.addObservation(t,time) self.obsTimeMask[tbin] = 1.0 else: log.debug('Bin %3i @mjd=%.3f already filled up with observations. Skipping...'%(tbin,time-2400000.5)) #print i return 0 #targets
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 reschedule(self, machine): self.machine = machine self.rq = Queue(-1) #programs = Program.query.all() #log.debug("rescheduling, found %d programs." % len(programs)) # for program in programs: # for obs in program.observations: # for exp in obs.exposures: # self.rq.put(exp) exps = Exposure.query.filter_by(finished=False).all() log.debug("rescheduling, found %d exposures." % len(exps)) for exp in exps: self.rq.put(exp) machine.wakeup()
def setJD(self, jd=None): ''' Configure time domain by specifing a julian day. It will use information on exposure time to build time bins that will be filled when selecting targets. ''' if not jd: site = Site() jd = np.floor(site.JD()) + 0.5 nightstart = _skysub.jd_sun_alt(self.sunMaxAlt, jd, self.sitelat, self.sitelong) nightend = _skysub.jd_sun_alt(self.sunMaxAlt, jd + 0.5, self.sitelat, self.sitelong) log.debug('Nigh Start @JD= %.3f # Night End @JD = %.3f' % (nightstart, nightend)) tbin = np.max([np.max(self.sciExpTime), np.max(self.stdExpTime) ]) * self.nfilters / 60. / 60. / 24. self.obsTimeBins = np.arange(nightstart, nightend + tbin, tbin) self.obsTimeMask = np.zeros(len(self.obsTimeBins)) self.obsTimeMask[-1] = 1.0 # Marking filled bins session = Session() scheduled = session.query(Program) for target in scheduled: tindex = np.abs(self.obsTimeBins - 2400000.5 - target.slewAt).argmin() self.obsTimeMask[tindex] = 1.0 self.isJD = True
def run(self): log.info("Starting scheduler machine") self.state(State.DIRTY) while self.state() != State.SHUTDOWN: if self.state() == State.OFF: log.debug("[off] will just sleep..") pass if self.state() == State.DIRTY: log.debug("[dirty] database changed, rescheduling...") self.scheduler.reschedule(self) self.state(State.IDLE) continue if self.state() == State.IDLE: log.debug("[idle] looking for something to do...") # find something to do exposure = self.scheduler.next() if exposure: log.debug("[idle] there is something to do, processing...") self.state(State.BUSY) self._process(exposure) continue # should'nt get here if any task was executed log.debug("[idle] there is nothing to do, sleeping...") elif self.state() == State.BUSY: log.debug("[busy] waiting tasks to finish..") pass elif self.state() == State.SHUTDOWN: log.debug("[shutdown] should die soon.") break # Rest In Pieces/Let Sleeping Dogs Lie self.sleep() log.debug('[shutdown] thread ending...')
def wakeup(self): self.__wakeUpCall.acquire() log.debug("Waking up") self.__wakeUpCall.notifyAll() self.__wakeUpCall.release()
def sleep(self): self.__wakeUpCall.acquire() log.debug("Sleeping") self.__wakeUpCall.wait() self.__wakeUpCall.release()
def run(self): log.info("Starting scheduler machine") self.state(State.OFF) # inject instruments on handlers self.executor.__start__() while self.state() != State.SHUTDOWN: if self.state() == State.OFF: log.debug("[off] will just sleep..") self.sleep() if self.state() == State.START: log.debug("[start] database changed, rescheduling...") self.scheduler.reschedule(self) self.state(State.IDLE) if self.state() == State.IDLE: log.debug("[idle] looking for something to do...") # find something to do program = self.scheduler.next() if program: log.debug("[idle] there is something to do, processing...") self.state(State.BUSY) self.currentProgram = program self._process(program) continue # should'nt get here if any task was executed log.debug("[idle] there is nothing to do, going offline...") self.currentProgram = None self.state(State.OFF) elif self.state() == State.BUSY: log.debug("[busy] waiting tasks to finish..") self.sleep() elif self.state() == State.STOP: log.debug("[stop] trying to stop current program") self.executor.stop() self.state(State.OFF) elif self.state() == State.SHUTDOWN: log.debug("[shutdown] trying to stop current program") self.executor.stop() log.debug("[shutdown] should die soon.") break log.debug('[shutdown] thread ending...')
# instruments just returns in case of abort, so we need to check handler # returned 'cause of abort or not if self.mustStop.isSet(): self.controller.actionComplete(action, SchedulerStatus.ABORTED) raise ProgramExecutionAborted() else: self.controller.actionComplete(action, SchedulerStatus.OK) except ProgramExecutionException, e: self.controller.actionComplete(action, SchedulerStatus.ERROR) raise except KeyError: log.debug("No handler to %s action. Skipping it" % action) finally: log.debug("[finish] took: %f s" % (time.time() - t0)) def stop(self): if self.currentHandler: self.mustStop.set() self.currentHandler.abort(self.currentAction) def _injectInstrument(self, handler): if not issubclass(handler, ActionHandler): return if not hasattr(handler.process, "__requires__"): return for instrument in handler.process.__requires__: try:
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: 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 except Exception, e: log.debug ("Handler (%s) raised an exception. Removing from subscribers list." % proxy) log.exception(e) excluded.append(handler) continue