Ejemplo n.º 1
0
 def ask_wc(self, key, ts, time, ttl):
     ret = set()
     # look for matching keys
     for cat, (_, lock, db) in listitems(self._cat):
         prefix = cat + '/' if cat != 'nocat' else ''
         with lock:
             for subkey, entry in iteritems(db):
                 if key not in prefix + subkey:
                     continue
                 # check for removed keys
                 if entry.value is None:
                     continue
                 # check for expired keys
                 op = entry.expired and OP_TELLOLD or OP_TELL
                 if entry.ttl:
                     if ts:
                         ret.add('%r+%s@%s%s%s\n' %
                                 (entry.time, entry.ttl, prefix + subkey,
                                  op, entry.value))
                     else:
                         ret.add(prefix + subkey + op + entry.value + '\n')
                 elif ts:
                     ret.add('%r@%s%s%s\n' %
                             (entry.time, prefix + subkey, op, entry.value))
                 else:
                     ret.add(prefix + subkey + op + entry.value + '\n')
     return [''.join(ret)]
Ejemplo n.º 2
0
 def doStatus(self, maxage=0):
     st = multiStatus(listitems(self._adevs), maxage)
     if st[0] == status.OK:
         # check position
         try:
             self.doRead(maxage)
         except PositionError as e:
             return status.NOTREACHED, str(e)
     return st
Ejemplo n.º 3
0
 def statusinfo(self):
     self.log.info('got SIGUSR2 - current stacktraces for each thread:')
     active = threading._active
     for tid, frame in listitems(sys._current_frames()):
         if tid in active:
             name = active[tid].getName()
         else:
             name = str(tid)
         self.log.info('%s: %s', name,
                       ''.join(traceback.format_stack(frame)))
Ejemplo n.º 4
0
    def updateAliasList(self):
        setups, _ = self._calculateSetups()
        # get includes as well
        seen = set()

        def add_includes(s):
            if s in seen or s not in self._setupinfo:
                return
            seen.add(s)
            for inc in self._setupinfo[s]['includes']:
                add_includes(inc)
                setups.add(inc)

        for setup in setups.copy():
            add_includes(setup)
        # now collect alias config
        alias_config = {}
        for setup in setups:
            if 'alias_config' in self._setupinfo[setup]:
                aliasconfig = self._setupinfo[setup]['alias_config']
                for aliasname, targets in aliasconfig.items():
                    for (target, prio) in targets.items():
                        alias_config.setdefault(aliasname, []).append(
                            (target, prio))
        # sort by priority
        for aliasname in alias_config:
            alias_config[aliasname].sort(key=lambda x: -x[1])
        # create/update widgets
        layout = self.aliasGroup.layout()
        # only preselect previous aliases if we have the same choices for them
        # as in the beginning
        for aliasname in sorted(alias_config):
            preselect = self._prev_alias_config is None or \
                (alias_config.get(aliasname) ==
                 self._prev_alias_config.get(aliasname))
            selections = [x[0] for x in alias_config[aliasname]]
            if aliasname in self._aliasWidgets:
                self._aliasWidgets[aliasname].setSelections(
                    selections, preselect
                    and self._prev_aliases.get(aliasname))
            else:
                wid = self._aliasWidgets[aliasname] = AliasWidget(
                    self, aliasname, selections, preselect
                    and self._prev_aliases.get(aliasname))
                layout.addWidget(wid)
        for name, wid in listitems(self._aliasWidgets):
            if name not in alias_config:
                layout.takeAt(layout.indexOf(wid)).widget().deleteLater()
                del self._aliasWidgets[name]
        if alias_config:
            self.aliasGroup.show()
        else:
            self.aliasGroup.hide()
        self._alias_config = alias_config
Ejemplo n.º 5
0
def fixup_stacked_devices(logger, devdict):
    """
    Replace <adevname> = Device(..) entries in devices dict with a proper
    name and move the device definition under that name.
    """
    def add_new_dev(devname, subname, devconfig):
        # guess a name:
        newname = '%s_%s' % (devname, subname)
        while newname in devdict:
            logger.error('Device %r already exists, but is also a '
                         'subdevice of %r which should be renamed',
                         newname, devname)
            newname = '_' + newname
        # set subDevice lowlevel if not specified otherwise
        if 'lowlevel' not in devconfig[1]:
            devconfig[1]['lowlevel'] = True
        # 'rename' device, keeping logical connection
        devdict[newname] = devconfig
        return newname

    patched = True
    while patched:
        patched = False
        # iter over all devices
        for devname, dev in listitems(devdict):
            # iter over all key=value pairs for dict
            for subname, config in listitems(dev[1]):
                if isinstance(config, Device):  # need to fixup!
                    newname = add_new_dev(devname, subname, config)
                    dev[1][subname] = newname
                    patched = True
                elif isinstance(config, (tuple, list)) and \
                        any(isinstance(e, Device) for e in config):
                    dev[1][subname] = list(config)
                    for idx, item in enumerate(config):
                        if isinstance(item, Device):
                            subentryname = '%s%d' % (subname, idx + 1)
                            newname = add_new_dev(devname, subentryname, item)
                            dev[1][subname][idx] = newname
                            patched = True
    return devdict
Ejemplo n.º 6
0
def devIter(devices, baseclass=None, onlydevs=True, allwaiters=False):
    """Filtering generator over the given devices.

    Iterates over the given devices.  If the *baseclass* argument is specified
    (not ``None``), filter out (ignore) those devices which do not belong to
    the given baseclass.  If the boolean *onlydevs* argument is false, yield
    ``(name, devices)`` tuples otherwise just the devices.

    If *allwaiters* is true, recursively include devices given by devices'
    ``_getWaiters`` methods.

    The given devices argument can either be a dictionary (_adevs, _sdevs,...)
    or a list of (name, device) tuples or a simple list of devices.
    """
    if baseclass is None:
        # avoid import loop and still default to Device
        from nicos.core.device import Device
        baseclass = Device
    # convert dict to list of name:dev tuples
    if isinstance(devices, dict):
        devices = listitems(devices)
    else:
        # we iterate twice: make sure to convert generators
        # to a list first
        devices = list(devices)
        try:  # to convert list of devices into desired format
            devices = [(dev.name, dev) for dev in devices if dev]
        except AttributeError:
            pass  # not convertible, must be right format already...
    for devname, dev in devices:
        # handle _adevs style entries correctly
        if isinstance(dev, (tuple, list)):
            for subdev in dev:
                if isinstance(subdev, baseclass):
                    if allwaiters:
                        for subsubdev in devIter(subdev._getWaiters(),
                                                 baseclass, onlydevs,
                                                 allwaiters):
                            yield subsubdev
                    yield subdev if onlydevs else (subdev.name, subdev)
        else:
            if isinstance(dev, baseclass):
                if allwaiters:
                    for subdev in devIter(dev._getWaiters(), baseclass,
                                          onlydevs, allwaiters):
                        yield subdev
                yield dev if onlydevs else (devname, dev)
Ejemplo n.º 7
0
 def _collectMetaInformation(self, update_headerinfo=None):
     bycategory = {}
     metainfo = self.dataset.metainfo
     for (device, key), (_, val, unit, category) in iteritems(metainfo):
         if category:
             bycategory.setdefault(category, []).append(
                 ('%s_%s' % (device, key), (val + ' ' + unit).strip()))
     if update_headerinfo is None:
         update_headerinfo = getattr(self.sink, 'update_headerinfo',
                                     self.update_headerinfo)
     if update_headerinfo:
         # put count result in its own category: 'result'
         # note: status may need to be update manually as it is not
         #       collected in the values :(
         # note2: as we may be called during counting, some devices
         #        may be busy: this may irritate users :(
         bycategory['result'] = results = []
         for devname, val in listitems(self.dataset.values):
             device = session.getDevice(devname)
             if (devname, 'value') in metainfo:
                 # re-use the category
                 _, _, unit, category = metainfo[(devname, 'value')]
             else:
                 unit = device.unit
                 category = 'result'
             bycategory.setdefault(category,[]).append(
                 ('%s_value' % devname, (str(val) + ' ' + unit).strip()))
             # refresh status as well
             stat = device.status()
             # also map stat[0] to a string
             if stat[1]:
                 stat = ('%s_status' % devname, ('%s: %s' %
                     (statuses[stat[0]].lower(), stat[1].strip())))
             else:
                 stat = ('%s_status' % devname, statuses[stat[0]].lower())
             bycategory[category].append(stat)
     # collect countresults (if already existing)
     if self.dataset.results:
         bycategory['result'] = results = []
         for detname, detvalue in zip(self.dataset.detvalueinfo,
                                      self.dataset.detvaluelist):
             results.append((detname.name, str(detvalue)))
     return bycategory
Ejemplo n.º 8
0
 def statusinfo(self):
     self.log.info('got SIGUSR2')
     if self._setup is not None:
         info = []
         for worker in itervalues(self._workers):
             wname = worker.getName()
             if worker.is_alive():
                 info.append('%s: alive' % wname)
             else:
                 info.append('%s: dead' % wname)
         self.log.info(', '.join(info))
         self.log.info('current stacktraces for each thread:')
         active = threading._active
         for tid, frame in listitems(sys._current_frames()):
             if tid in active:
                 name = active[tid].getName()
             else:
                 name = str(tid)
             self.log.info('%s: %s', name,
                           ''.join(traceback.format_stack(frame)))
Ejemplo n.º 9
0
 def _wait_master_nt(self):
     # this is the same as _wait_master, but with active polling instead
     # of using os.wait(), which does not exist on Windows
     while True:
         sleep(0.5)
         if not self._children:
             break
         for setup, ch in listitems(self._children):
             ret = ch.poll()
             if ret is not None:
                 # a process exited; restart if necessary
                 del self._childpids[ch.pid]
                 del self._children[setup]
                 if setup in self._setups and not self._stoprequest:
                     session.log.warning(
                         '%s poller terminated with %s, '
                         'restarting', setup, ret)
                     self._start_child(setup)
                     break
                 else:
                     session.log.info('%s poller terminated with %s', setup,
                                      ret)
     session.log.info('all pollers terminated')
Ejemplo n.º 10
0
def kwscount(**arguments):
    """Move sample and devices into place followed by a count.

    This takes KWS-specific circumstances such as sample time factor into
    account.

    Example:

    >>> kwscount(sample=1, selector='12A', resolution='2m', sample_pos='1.3m', time=3600)

    Keywords for standard instrument components are:

    * sample (sample number or name if unique, defaults to no sample change)
    * selector (must be present)
    * resolution (must be present)
    * sample_pos (must be present)
    * detector (must be present)
    * beamstop (defaults to out)
    * polarizer (defaults to out)
    * chopper (defaults to off)

    Any other keywords are interpreted as devices names and the target values.
    """
    def sort_key(kv):
        try:
            # main components move first, in selected order
            return (0, DEFAULT.index(kv[0]))
        except ValueError:
            # all other devices move last, sorted by devname
            return (1, kv[0])

    # check that all required components are present, and put defaults for
    # optional components
    if 'selector' not in arguments:
        raise UsageError('kwscount must have a value for the selector')
    if 'detector' not in arguments:
        raise UsageError('kwscount must have a value for the detector')
    if 'sample_pos' not in arguments:
        raise UsageError('kwscount must have a value for the sample_pos')
    if 'detector' not in arguments:
        raise UsageError('kwscount must have a value for the detector')
    if 'beamstop' not in arguments:
        arguments['beamstop'] = 'out'
    if 'polarizer' not in arguments:
        arguments['polarizer'] = 'out'
    if 'chopper' not in arguments:
        arguments['chopper'] = 'off'
    # leave space between kwscounts
    session.log.info('')
    # measurement time
    meastime = arguments.pop('time', 0)
    # select sample
    sample = arguments.pop('sample', None)
    # move devices
    waiters = []
    # the order is important!
    devs = listitems(arguments)
    devs.sort(key=sort_key)
    # add moved devices to sampleenv
    _fixupSampleenv(devs)
    # start devices
    for devname, value in devs:
        if devname == 'chopper':
            # currently a no-op
            continue
        dev = session.getDevice(devname, Moveable)
        dev.start(value)
        if devname == 'selector':
            dev2 = session.getDevice('sel_speed')
            session.log.info('%-12s --> %s (%s)', devname, dev.format(value),
                             dev2.format(dev2.target, unit=True))
        else:
            session.log.info('%-12s --> %s', devname,
                             dev.format(value, unit=True))
        waiters.append(dev)
    # select and wait for sample here
    if sample is not None:
        session.experiment.sample.select(sample)
    # now wait for everyone else
    multiWait(waiters)
    # count
    session.log.info('Now counting for %d seconds...', meastime)
    count(t=meastime)
Ejemplo n.º 11
0
    def _server_thread(self):
        self.log.info('server starting')

        # bind UDP broadcast socket
        self.log.debug('trying to bind to UDP broadcast')
        self._serversocket_udp = self._bind_to('', 'udp')[0]
        if self._serversocket_udp:
            self.log.info('UDP bound to broadcast')

        # now try to bind TCP socket, include 'MUST WORK' standalone names
        self.log.debug('trying to bind to %s', self.server)
        self._serversocket, self._boundto = self._bind_to(self.server)

        # one of the must have worked, otherwise continuing makes no sense
        if not self._serversocket and not self._serversocket_udp:
            self._stoprequest = True
            self.log.error("couldn't bind any sockets, giving up!")
            return

        if not self._boundto:
            self.log.warning('starting main loop only bound to UDP broadcast')
        else:
            self.log.info('TCP bound to %s:%s', self._boundto[0],
                          self._boundto[1])

        # now enter main serving loop
        while not self._stoprequest:
            # loop through connections, first to remove dead ones,
            # secondly to try to reconnect
            for addr, client in listitems(self._connected):
                if not client.is_active():  # dead or stopped
                    self.log.info('client connection %s closed', addr)
                    client.closedown()
                    client.join()  # wait for threads to end
                    del self._connected[addr]

            # now check for additional incoming connections
            # build list of things to check
            selectlist = []
            if self._serversocket:
                selectlist.append(self._serversocket)
            if self._serversocket_udp:
                selectlist.append(self._serversocket_udp)

            # 3 times client-side timeout
            res = select.select(selectlist, [], [], CYCLETIME * 3)
            if not res[0]:
                continue  # nothing to read -> continue loop
            # lock aginst code in self.quit
            with self._connectionLock:
                if self._stoprequest:
                    break
                if self._serversocket in res[0]:
                    # TCP connection came in
                    conn, addr = self._serversocket.accept()
                    addr = 'tcp://%s:%d' % addr
                    self.log.info('new connection from %s', addr)
                    self._connected[addr] = CacheWorker(self._attached_db,
                                                        conn,
                                                        name=addr,
                                                        loglevel=self.loglevel)
                elif self._serversocket_udp in res[0]:
                    # UDP data came in
                    data, addr = self._serversocket_udp.recvfrom(3072)
                    nice_addr = 'udp://%s:%d' % addr
                    self.log.info('new connection from %s', nice_addr)
                    self._connected[nice_addr] = CacheUDPWorker(
                        self._attached_db,
                        self._serversocket_udp,
                        name=nice_addr,
                        data=data,
                        remoteaddr=addr,
                        loglevel=self.loglevel)
        if self._serversocket:
            closeSocket(self._serversocket)
        self._serversocket = None
Ejemplo n.º 12
0
def readSetup(infodict, modname, filepath, all_setups, logger):
    try:
        with open(filepath, 'rb') as modfile:
            code = modfile.read()
    except IOError as err:
        logger.exception('Could not read setup '
                         'module %r: %s', filepath, err)
        return
    ns = prepareNamespace(modname, filepath, all_setups)
    try:
        exec_(code, ns)
    except Exception as err:
        logger.exception('An error occurred while processing '
                         'setup %r: %s', filepath, err)
        return
    devices = fixup_stacked_devices(logger, ns.get('devices', {}))
    for devname in devices:
        if not nicosdev_re.match(devname):
            logger.exception('While processing setup %r: device name %r is '
                             'invalid, names must be Python identifiers',
                             filepath, devname)
            return
    info = {
        'description': ns.get('description', modname),
        'group': ns.get('group', 'optional'),
        'sysconfig': ns.get('sysconfig', {}),
        'includes': ns.get('includes', []),
        'excludes': ns.get('excludes', []),
        'modules': ns.get('modules', []),
        'devices': devices,
        'alias_config': ns.get('alias_config', {}),
        'startupcode': ns.get('startupcode', ''),
        'display_order': ns.get('display_order', 50),
        'extended': ns.get('extended', {}),
        'filenames': [filepath] + list(ns.get('_dep_files', ())),
        'monitor_blocks': ns.get('monitor_blocks', {}),
        'watch_conditions': ns.get('watch_conditions', []),
    }
    if info['group'] not in SETUP_GROUPS:
        logger.warning('Setup %s has an invalid group (valid groups '
                       'are: %s)', modname, ', '.join(SETUP_GROUPS))
        info['group'] = 'optional'
    if modname in infodict:
        # setup already exists; override/extend with new values
        oldinfo = infodict[modname] or {}
        oldinfo['description'] = ns.get('description',
                                        oldinfo['description'])
        oldinfo['group'] = ns.get('group', oldinfo['group'])
        oldinfo['sysconfig'].update(info['sysconfig'])
        oldinfo['includes'].extend(info['includes'])
        oldinfo['excludes'].extend(info['excludes'])
        oldinfo['modules'].extend(info['modules'])
        oldinfo['devices'].update(info['devices'])
        # remove devices overridden by "None" entries completely
        for devname, value in listitems(oldinfo['devices']):
            if value is None:
                del oldinfo['devices'][devname]
        oldinfo['startupcode'] += '\n' + info['startupcode']
        oldinfo['alias_config'].update(info['alias_config'])
        oldinfo['display_order'] = ns.get('display_order',
                                          oldinfo['display_order'])
        oldinfo['extended'].update(info['extended'])
        oldinfo['filenames'].extend(info['filenames'])
        oldinfo['monitor_blocks'].update(info['monitor_blocks'])
        oldinfo['watch_conditions'].extend(info['watch_conditions'])
        logger.debug('%r setup partially merged with version '
                     'from parent directory', modname)
    else:
        infodict[modname] = info