Exemple #1
0
    def __init__(self,
                 name,
                 session,
                 managerlocation=None,
                 otherdatabinder=None,
                 otherdbdatakeeper=None,
                 tcpport=None,
                 launcher=None,
                 panel=None):
        self.name = name
        self.panel = panel

        self.initializeLogger()

        self.managerclient = None

        if session is None or isinstance(session, leginondata.SessionData):
            self.session = session
        else:
            raise TypeError('session must be of proper type')

        self.launcher = launcher

        if otherdatabinder is None:
            name = DataBinder.__name__
            databinderlogger = gui.wx.Logging.getNodeChildLogger(name, self)
            self.databinder = DataBinder(self,
                                         databinderlogger,
                                         tcpport=tcpport)
        else:
            self.databinder = otherdatabinder
        if otherdbdatakeeper is None:
            self.dbdatakeeper = sinedon.getConnection('leginondata')
        else:
            self.dbdatakeeper = otherdbdatakeeper

        self.confirmationevents = {}
        self.eventswaiting = {}
        self.ewlock = threading.Lock()

        #self.addEventInput(event.Event, self.logEventReceived)
        self.addEventInput(event.KillEvent, self.die)
        self.addEventInput(event.ConfirmationEvent, self.handleConfirmedEvent)
        self.addEventInput(event.SetManagerEvent, self.handleSetManager)
        self.addEventInput(event.ApplicationLaunchedEvent,
                           self.handleApplicationEvent)

        self.managerlocation = managerlocation
        if managerlocation is not None:
            try:
                self.setManager(self.managerlocation)
            except:
                self.logger.exception('exception in setManager')
                raise

        correctorclient.CorrectorClient.__init__(self)

        self.initializeSettings()
	def __init__(self, name, session, managerlocation=None, otherdatabinder=None, otherdbdatakeeper=None, tcpport=None, launcher=None, panel=None):
		self.name = name
		self.panel = panel
		
		self.initializeLogger()

		self.managerclient = None

		if session is None or isinstance(session, leginondata.SessionData):
			self.session = session
		else:
			raise TypeError('session must be of proper type')

		self.launcher = launcher

		if otherdatabinder is None:
			name = DataBinder.__name__
			databinderlogger = gui.wx.Logging.getNodeChildLogger(name, self)
			self.databinder = DataBinder(self, databinderlogger, tcpport=tcpport)
		else:
			self.databinder = otherdatabinder
		if otherdbdatakeeper is None:
			self.dbdatakeeper = sinedon.getConnection('leginondata')
		else:
			self.dbdatakeeper = otherdbdatakeeper

		self.confirmationevents = {}
		self.eventswaiting = {}
		self.ewlock = threading.Lock()

		#self.addEventInput(event.Event, self.logEventReceived)
		self.addEventInput(event.KillEvent, self.die)
		self.addEventInput(event.ConfirmationEvent, self.handleConfirmedEvent)
		self.addEventInput(event.SetManagerEvent, self.handleSetManager)
		self.addEventInput(event.ApplicationLaunchedEvent, self.handleApplicationEvent)

		self.managerlocation = managerlocation
		if managerlocation is not None:
			try:
				self.setManager(self.managerlocation)
			except:
				self.logger.exception('exception in setManager')
				raise

		correctorclient.CorrectorClient.__init__(self)

		self.initializeSettings()
Exemple #3
0
class Node(correctorclient.CorrectorClient):
    '''Atomic operating unit for performing tasks, creating data and events.'''
    panelclass = None
    eventinputs = [
        event.Event, event.KillEvent, event.ApplicationLaunchedEvent,
        event.ConfirmationEvent
    ]

    eventoutputs = [
        event.PublishEvent, event.NodeAvailableEvent,
        event.NodeUnavailableEvent, event.NodeInitializedEvent,
        event.NodeUninitializedEvent
    ]

    objectserviceclass = remotecall.NodeObjectService

    def __init__(self,
                 name,
                 session,
                 managerlocation=None,
                 otherdatabinder=None,
                 otherdbdatakeeper=None,
                 tcpport=None,
                 launcher=None,
                 panel=None):
        self.name = name
        self.panel = panel

        self.initializeLogger()

        self.managerclient = None

        if session is None or isinstance(session, leginondata.SessionData):
            self.session = session
        else:
            raise TypeError('session must be of proper type')

        self.launcher = launcher

        if otherdatabinder is None:
            name = DataBinder.__name__
            databinderlogger = gui.wx.Logging.getNodeChildLogger(name, self)
            self.databinder = DataBinder(self,
                                         databinderlogger,
                                         tcpport=tcpport)
        else:
            self.databinder = otherdatabinder
        if otherdbdatakeeper is None:
            self.dbdatakeeper = sinedon.getConnection('leginondata')
        else:
            self.dbdatakeeper = otherdbdatakeeper

        self.confirmationevents = {}
        self.eventswaiting = {}
        self.ewlock = threading.Lock()

        #self.addEventInput(event.Event, self.logEventReceived)
        self.addEventInput(event.KillEvent, self.die)
        self.addEventInput(event.ConfirmationEvent, self.handleConfirmedEvent)
        self.addEventInput(event.SetManagerEvent, self.handleSetManager)
        self.addEventInput(event.ApplicationLaunchedEvent,
                           self.handleApplicationEvent)

        self.managerlocation = managerlocation
        if managerlocation is not None:
            try:
                self.setManager(self.managerlocation)
            except:
                self.logger.exception('exception in setManager')
                raise

        correctorclient.CorrectorClient.__init__(self)

        self.initializeSettings()

    def testprint(self, msg):
        if testing:
            print msg

    # settings

    def initializeSettings(self, user=None):
        if not hasattr(self, 'settingsclass'):
            return

        # load the requested user settings
        if user is None:
            user = self.session['user']
        qsession = leginondata.SessionData(initializer={'user': user})
        qdata = self.settingsclass(initializer={
            'session': qsession,
            'name': self.name
        })
        settings = self.research(qdata, results=1)
        # if that failed, try to load default settings from DB
        if not settings:
            qdata = self.settingsclass(initializer={
                'isdefault': True,
                'name': self.name
            })
            settings = self.research(qdata, results=1)

        # if that failed, use hard coded defaults
        if not settings:
            self.settings = copy.deepcopy(self.defaultsettings)
        else:
            # get query result into usable form
            settings = settings[0]
            self.settings = settings.toDict(dereference=True)
            del self.settings['session']
            del self.settings['name']

        # check if None in any fields
        for key, value in self.settings.items():
            if value is None:
                if key in self.defaultsettings:
                    self.settings[key] = copy.deepcopy(
                        self.defaultsettings[key])

    def loadSettingsByID(self, id):
        if not hasattr(self, 'settingsclass'):
            return

        # load the requested row by id
        settings = self.settingsclass.direct_query(id)
        # if that failed, try to load default settings from DB
        if not settings:
            self.logger.error('no settings with id: %s' % (id, ))
            return

        # get query result into usable form
        self.settings = settings.toDict(dereference=True)
        del self.settings['session']
        del self.settings['name']

        # check if None in any fields
        for key, value in self.settings.items():
            if value is None:
                if key in self.defaultsettings:
                    self.settings[key] = copy.deepcopy(
                        self.defaultsettings[key])

        # set to GUI

    def setSettings(self, d, isdefault=False):
        self.settings = d
        sd = self.settingsclass.fromDict(d)
        sd['session'] = self.session
        sd['name'] = self.name
        if self.session['user']['username'] == 'administrator':
            sd['isdefault'] = True
        else:
            sd['isdefault'] = isdefault
        self.publish(sd, database=True, dbforce=True)
        self._checkSettings(sd)

    def _checkSettings(self, settings):
        if hasattr(self, 'checkSettings'):
            messages = self.checkSettings(settings)
        else:
            messages = []
        for message in messages:
            level = message[0]
            text = message[1]
            func = getattr(self.logger, level)
            func(text)

    def getSettings(self):
        return self.settings

    def initializeLogger(self):
        if hasattr(self, 'logger'):
            return
        self.logger = gui.wx.Logging.getNodeLogger(self)
        clientname = datatransport.Client.__name__
        self.clientlogger = gui.wx.Logging.getNodeChildLogger(clientname, self)

    def logToDB(self, record):
        '''insertes a logger record into the DB'''
        record_data = leginondata.LoggerRecordData(session=self.session)
        for atr in ('name', 'levelno', 'levelname', 'pathname', 'filename',
                    'module', 'lineno', 'created', 'thread', 'process',
                    'message', 'exc_info'):
            record_data[atr] = getattr(record, atr)
        self.publish(record_data, database=True, dbforce=True)

    # main, start/stop methods

    def start(self):
        self.onInitialized()
        self.outputEvent(event.NodeInitializedEvent())

    def onInitialized(self):
        if self.panel is None:
            return
        evt = gui.wx.Node.NodeInitializedEvent(self)
        self.panel.GetEventHandler().AddPendingEvent(evt)
        evt.event.wait()

    def setImage(self, image, typename=None):
        if image is not None:
            image = numpy.asarray(image, numpy.float32)
        evt = gui.wx.Events.SetImageEvent(image, typename)
        self.panel.GetEventHandler().AddPendingEvent(evt)

    def setTargets(self, targets, typename, block=False):
        evt = gui.wx.Events.SetTargetsEvent(targets, typename)
        if block:
            evt.event = threading.Event()
        self.panel.GetEventHandler().AddPendingEvent(evt)
        if block:
            evt.event.wait()

    def exit(self):
        '''Cleans up the node before it dies.'''
        try:
            self.objectservice._exit()
        except (AttributeError, TypeError):
            pass
        try:
            self.outputEvent(event.NodeUninitializedEvent(),
                             wait=True,
                             timeout=3.0)
            self.outputEvent(event.NodeUnavailableEvent())
        except (ConfirmationTimeout, datatransport.TransportError):
            pass
        self.delEventInput()
        if self.launcher is not None:
            self.launcher.onDestroyNode(self)
            if self.databinder is self.launcher.databinder:
                return
        self.databinder.exit()

    def die(self, ievent=None):
        '''Tell the node to finish and call exit.'''
        self.exit()
        if ievent is not None:
            self.confirmEvent(ievent)

    # location method
    def location(self):
        location = {}
        location['hostname'] = socket.gethostname().lower()
        if self.launcher is not None:
            location['launcher'] = self.launcher.name
        else:
            location['launcher'] = None
        location['data binder'] = self.databinder.location()
        return location

    # event input/output/blocking methods

    def eventToClient(self, ievent, client, wait=False, timeout=None):
        '''
                base method for sending events to a client
                ievent - event instance
                client - client instance
                wait - True/False, sould confirmation be sent back
                timeout - how long (seconds) to wait for confirmation before
                   raising a ConfirmationTimeout
                '''
        if wait:
            ## prepare to wait (but don't wait yet)
            wait_id = ievent.dmid
            ievent['confirm'] = wait_id
            self.ewlock.acquire()
            self.eventswaiting[wait_id] = threading.Event()
            eventwait = self.eventswaiting[wait_id]
            self.ewlock.release()

        ### send event and cross your fingers
        try:
            client.send(ievent)
            #self.logEvent(ievent, status='%s eventToClient' % (self.name,))
        except datatransport.TransportError:
            # make sure we don't wait for an event that failed
            if wait:
                eventwait.set()
            raise
        except Exception, e:
            self.logger.exception('Error sending event to client: %s' % e)
            raise

        confirmationevent = None

        if wait:
            ### this wait should be released
            ### by handleConfirmedEvent()
            eventwait.wait(timeout)
            notimeout = eventwait.isSet()
            self.ewlock.acquire()
            try:
                confirmationevent = self.confirmationevents[wait_id]
                del self.confirmationevents[wait_id]
                del self.eventswaiting[wait_id]
            except KeyError:
                self.logger.warning('This could be bad to except KeyError')
            self.ewlock.release()
            if not notimeout:
                raise ConfirmationTimeout(str(ievent))
            if confirmationevent['status'] == 'no binding':
                raise ConfirmationNoBinding(
                    '%s from %s not bound to any node' %
                    (ievent.__class__.__name__, ievent['node']))

        return confirmationevent
class Node(correctorclient.CorrectorClient):
	'''Atomic operating unit for performing tasks, creating data and events.'''
	panelclass = None
	eventinputs = [event.Event,
									event.KillEvent,
									event.ApplicationLaunchedEvent,
									event.ConfirmationEvent]

	eventoutputs = [event.PublishEvent,
									event.NodeAvailableEvent,
									event.NodeUnavailableEvent,
									event.NodeInitializedEvent,
									event.NodeUninitializedEvent]

	objectserviceclass = remotecall.NodeObjectService

	def __init__(self, name, session, managerlocation=None, otherdatabinder=None, otherdbdatakeeper=None, tcpport=None, launcher=None, panel=None):
		self.name = name
		self.panel = panel
		
		self.initializeLogger()

		self.managerclient = None

		if session is None or isinstance(session, leginondata.SessionData):
			self.session = session
		else:
			raise TypeError('session must be of proper type')

		self.launcher = launcher

		if otherdatabinder is None:
			name = DataBinder.__name__
			databinderlogger = gui.wx.Logging.getNodeChildLogger(name, self)
			self.databinder = DataBinder(self, databinderlogger, tcpport=tcpport)
		else:
			self.databinder = otherdatabinder
		if otherdbdatakeeper is None:
			self.dbdatakeeper = sinedon.getConnection('leginondata')
		else:
			self.dbdatakeeper = otherdbdatakeeper

		self.confirmationevents = {}
		self.eventswaiting = {}
		self.ewlock = threading.Lock()

		#self.addEventInput(event.Event, self.logEventReceived)
		self.addEventInput(event.KillEvent, self.die)
		self.addEventInput(event.ConfirmationEvent, self.handleConfirmedEvent)
		self.addEventInput(event.SetManagerEvent, self.handleSetManager)
		self.addEventInput(event.ApplicationLaunchedEvent, self.handleApplicationEvent)

		self.managerlocation = managerlocation
		if managerlocation is not None:
			try:
				self.setManager(self.managerlocation)
			except:
				self.logger.exception('exception in setManager')
				raise

		correctorclient.CorrectorClient.__init__(self)

		self.initializeSettings()

	def testprint(self,msg):
		if testing:
			print msg

	# settings

	def initializeSettings(self, user=None):
		if not hasattr(self, 'settingsclass'):
			return

		settings = self.reseachDBSettings(self.settingsclass, self.name, user)

		# if that failed, use hard coded defaults
		if not settings:
			self.settings = copy.deepcopy(self.defaultsettings)
		else:
			# get query result into usable form
			settings = settings[0]
			self.settings = settings.toDict(dereference=True)
			del self.settings['session']
			del self.settings['name']

		# check if None in any fields
		for key,value in self.settings.items():
			if value is None:
				if key in self.defaultsettings:
					self.settings[key] = copy.deepcopy(self.defaultsettings[key])

	def reseachDBSettings(self, settingsclass, inst_alias, user=None):
		# load the requested user settings
		if user is None:
			user = self.session['user']
		qsession = leginondata.SessionData(initializer={'user': user})
		qdata = settingsclass(initializer={'session': qsession,
																						'name': inst_alias})
		settings = self.research(qdata, results=1)
		# if that failed, try to load default settings from DB
		if not settings:
			qdata = settingsclass(initializer={'isdefault': True, 'name': self.name})
			settings = self.research(qdata, results=1)
		return settings

	def loadSettingsByID(self, id):
		if not hasattr(self, 'settingsclass'):
			return

		# load the requested row by id
		settings = self.settingsclass.direct_query(id)
		# if that failed, try to load default settings from DB
		if not settings:
			self.logger.error('no settings with id: %s' % (id,))
			return

		# get query result into usable form
		self.settings = settings.toDict(dereference=True)
		del self.settings['session']
		del self.settings['name']

		# check if None in any fields
		for key,value in self.settings.items():
			if value is None:
				if key in self.defaultsettings:
					self.settings[key] = copy.deepcopy(self.defaultsettings[key])

		# set to GUI

	def setSettings(self, d, isdefault=False):
		self.settings = d
		sd = self.settingsclass.fromDict(d)
		sd['session'] = self.session
		sd['name'] = self.name
		if self.session['user']['username'] == 'administrator':
			sd['isdefault'] = True
		else:
			sd['isdefault'] = isdefault
		self.publish(sd, database=True, dbforce=True)
		self._checkSettings(sd)

	def _checkSettings(self, settings):
		if hasattr(self, 'checkSettings'):
			messages = self.checkSettings(settings)
		else:
			messages = []
		for message in messages:
			level = message[0]
			text = message[1]
			func = getattr(self.logger, level)
			func(text)

	def getSettings(self):
		return self.settings

	def initializeLogger(self):
		if hasattr(self, 'logger'):
			return
		self.logger = gui.wx.Logging.getNodeLogger(self)
		clientname = datatransport.Client.__name__
		self.clientlogger = gui.wx.Logging.getNodeChildLogger(clientname, self)

	def logToDB(self, record):
		'''insertes a logger record into the DB'''
		record_data = leginondata.LoggerRecordData(session=self.session)
		for atr in ('name','levelno','levelname','pathname','filename','module','lineno','created','thread','process','message','exc_info'):
			record_data[atr] = getattr(record,atr)
		self.publish(record_data, database=True, dbforce=True)

	# main, start/stop methods

	def start(self):
		self.onInitialized()
		self.outputEvent(event.NodeInitializedEvent())

	def onInitialized(self):
		if self.panel is None:
			return
		evt = gui.wx.Node.NodeInitializedEvent(self)
		self.panel.GetEventHandler().AddPendingEvent(evt)
		evt.event.wait()

	def setImage(self, image, typename=None):
		if image is not None:
			image = numpy.asarray(image, numpy.float32)
		evt = gui.wx.Events.SetImageEvent(image, typename)
		self.panel.GetEventHandler().AddPendingEvent(evt)

	def setTargets(self, targets, typename, block=False):
		evt = gui.wx.Events.SetTargetsEvent(targets, typename)
		if block:
			evt.event = threading.Event()
		self.panel.GetEventHandler().AddPendingEvent(evt)
		if block:
			evt.event.wait()

	def exit(self):
		'''Cleans up the node before it dies.'''
		try:
			self.objectservice._exit()
		except (AttributeError, TypeError):
			pass
		try:
			self.outputEvent(event.NodeUninitializedEvent(), wait=True,
																										timeout=3.0)
			self.outputEvent(event.NodeUnavailableEvent())
		except (ConfirmationTimeout, datatransport.TransportError):
			pass
		self.delEventInput()
		if self.launcher is not None:
			self.launcher.onDestroyNode(self)
			if self.databinder is self.launcher.databinder:
				return
		self.databinder.exit()

	def die(self, ievent=None):
		'''Tell the node to finish and call exit.'''
		self.exit()
		if ievent is not None:
			self.confirmEvent(ievent)

	# location method
	def location(self):
		location = {}
		location['hostname'] = socket.gethostname().lower()
		if self.launcher is not None:
			location['launcher'] = self.launcher.name
		else:
			location['launcher'] = None
		location['data binder'] = self.databinder.location()
		return location
	# event input/output/blocking methods

	def eventToClient(self, ievent, client, wait=False, timeout=None):
		'''
		base method for sending events to a client
		ievent - event instance
		client - client instance
		wait - True/False, sould confirmation be sent back
		timeout - how long (seconds) to wait for confirmation before
		   raising a ConfirmationTimeout
		'''
		if wait:
			## prepare to wait (but don't wait yet)
			wait_id = ievent.dmid
			ievent['confirm'] = wait_id
			self.ewlock.acquire()
			self.eventswaiting[wait_id] = threading.Event()
			eventwait = self.eventswaiting[wait_id]
			self.ewlock.release()

		### send event and cross your fingers
		try:
			client.send(ievent)
			#self.logEvent(ievent, status='%s eventToClient' % (self.name,))
		except datatransport.TransportError:
			# make sure we don't wait for an event that failed
			if wait:
				eventwait.set()
			raise
		except Exception, e:
			self.logger.exception('Error sending event to client: %s' % e)
			raise

		confirmationevent = None

		if wait:
			### this wait should be released 
			### by handleConfirmedEvent()
			eventwait.wait(timeout)
			notimeout = eventwait.isSet()
			self.ewlock.acquire()
			try:
				confirmationevent = self.confirmationevents[wait_id]
				del self.confirmationevents[wait_id]
				del self.eventswaiting[wait_id]
			except KeyError:
				self.logger.warning('This could be bad to except KeyError')
			self.ewlock.release()
			if not notimeout:
				raise ConfirmationTimeout(str(ievent))
			if confirmationevent['status'] == 'no binding':
				raise ConfirmationNoBinding('%s from %s not bound to any node' % (ievent.__class__.__name__, ievent['node']))

		return confirmationevent