示例#1
0
文件: script.py 项目: ess-dmsc/nicos
 def exec_script(self, code, user, handler):
     # execute code in the script namespace (this is called not from
     # the script thread, but from a handle thread)
     self.thread_data.user = user
     temp_request = ScriptRequest(code, None, user)
     temp_request.parse()
     session.log.log(INPUT, formatScript(temp_request, '---'))
     self.last_handler = weakref.ref(handler)
     try:
         for block in temp_request.code:
             exec(block, self.namespace)
     finally:
         self.last_handler = None
示例#2
0
文件: script.py 项目: ess-dmsc/nicos
    def update(self, text, reason, controller, user):
        """Update the code with a new script.

        This method is called from a different thread than execute(),
        so we must unset the _run flag before doing anything to
        self.curblock, self.code or self.blocks.
        """
        if not self.blocks:
            raise ScriptError('cannot update single-line script')
        text = fixupScript(text)
        newcode, newblocks = splitBlocks(text)
        # stop execution after the current block
        self._run.clear()
        curblock = self.curblock  # this may be off by one
        try:
            # make sure that everything that has already been executed matches
            if curblock >= len(newblocks):
                # insufficient number of new blocks
                raise ScriptError('new script too short')
            # compare all executed blocks
            for i in range(curblock + 1):
                if not self._compare(self.blocks[i], newblocks[i]):
                    raise ScriptError('new script differs in already executed '
                                      'part of the code')
            # everything is ok, replace the script and the remaining blocks
            self.text = text
            session.scriptEvent('update', (self.name, self.text))
            # also set the updating user as the new user of the script
            self.user = user
            if session._experiment and session.mode == MASTER:
                scr = list(session.experiment.scripts)  # convert readonly list
                scr[self._exp_script_index] = self.text
                session.experiment.scripts = scr
            updateLinecache('<script>', text)
            self.code, self.blocks = newcode, newblocks
            self.resetSimstate()
            # let the client know of the update
            controller.eventfunc('processing', self.serialize())
            updatemsg = 'UPDATE (%s)' % reason if reason else 'UPDATE'
            session.log.log(INPUT, formatScript(self, updatemsg))
        finally:
            # let the script continue execution in any case
            self._run.set()
示例#3
0
文件: script.py 项目: ess-dmsc/nicos
 def execute(self, controller):
     """Execute the script in the given namespace, using "controller"
     to execute individual blocks.
     """
     session.scriptEvent('start', (self.name, self.text))
     session.countloop_request = None  # reset any pause flag from before
     # this is to allow the traceback module to report the script's
     # source code correctly
     updateLinecache('<script>', self.text)
     # note: checking session._experiment since using session.experiment
     # would try to create the device, which means you can't execute any
     # command when the experiment fails
     if session._experiment and session.mode == MASTER:
         session.experiment.scripts += [self.text]
         self._exp_script_index = len(session.experiment.scripts) - 1
     if self.name:
         session.elogEvent('scriptbegin', self.name)
         session.beginActionScope(path.basename(self.name))
     # notify clients of "input"
     session.log.log(INPUT, formatScript(self))
     try:
         while self.curblock < len(self.code) - 1:
             self._run.wait()
             self.curblock += 1
             self.blockStart = time.time()
             self.emitETA(controller)
             controller.start_exec(self.code[self.curblock],
                                   controller.namespace, None,
                                   self.settrace)
     finally:
         if self.name:
             session.endActionScope()
         if session._experiment and session.mode == MASTER:
             session.experiment.scripts = session.experiment.scripts[:-1]
         if self.name:
             session.elogEvent('scriptend', self.name)
示例#4
0
文件: script.py 项目: ess-dmsc/nicos
    def script_thread_entry(self):
        """The script execution thread entry point.  This thread executes setup
        code, then waits for scripts on self.queue.  The script is then
        executed in the context of self.namespace, using the controller (self)
        to watch execution.
        """
        self.log.debug('script_thread (re)started')
        session.script_thread_id = current_thread().ident
        try:
            self.namespace['NicosSetup'] = self._setup
            # and put it in the queue as the first request
            request = ScriptRequest('NicosSetup()',
                                    'setting up NICOS',
                                    system_user,
                                    quiet=True,
                                    format='py')
            self.new_request(request, notify=False)

            while 1:
                # get a script (or other request) from the queue
                request = self.queue.get()
                self.thread_data.user = request.user

                if isinstance(request, EmergencyStopRequest):
                    self.log.info('executing estop request from %s',
                                  request.user.name)
                    self.execute_estop(request.user.name)
                    continue
                elif not isinstance(request, ScriptRequest):
                    self.log.error('unknown request: %s', request)
                    continue
                self.log.info('processing script %s by %s', request.reqid,
                              request.user.name)
                self.reqid_work = request.reqid
                if session.cache and self.autosim:
                    self.simulate_request(request, quiet=True)
                    request.setSimstate('running')
                # notify clients that we're processing this request now
                self.eventfunc('processing', request.serialize())
                # parse the script and split it into blocks
                try:
                    self.current_script = request
                    self.current_script.parse()
                except Exception:
                    session.log.log(INPUT, formatScript(request))
                    session.logUnhandledException(cut_frames=1)
                    continue
                try:
                    self.current_script.execute(self)
                except ControlStop as err:
                    if err.args[0] == 'emergency stop':
                        # block all pending requests (should have been done
                        # already, but to be on the safe side do it here again)
                        self.block_all_requests()
                        self.execute_estop(err.args[2])
                    else:
                        # in this case, we have already blocked all scripts
                        # queued before the "stop" command was given; scripts
                        # that are queued after that should be executed, so
                        # we don't block requests here
                        session.log.info('Script stopped by %s', err.args[2])
                except BdbQuit as err:  # pylint: disable=bad-except-order
                    session.log.error('Script stopped through debugger')
                except Exception as err:  # pylint: disable=bad-except-order
                    # the topmost two frames are still in the
                    # daemon, so don't display them to the user
                    # perhaps also send an error notification
                    try:
                        session.scriptEvent('exception', sys.exc_info())
                    except Exception:
                        # last resort: do not exit script thread even if we
                        # can't handle this exception
                        pass
                if self.debugger:
                    self.debug_end(tracing=False)
                session.clearActions()
                session.scriptEvent('finish', None)
        except Exception:
            self.log.exception('unhandled exception in script thread')
            session.log.error('internal error in NICOS daemon, please restart')
        finally:
            self.thread = None