@_execute_trace_decorator()
def execute(
    object, notifier, command, vids,
    args = (), kwargs = {}, timeout = None, retry = None, raw = False):
    #
    # emtpy sets fail to no RPC. still, match the type the caller expects.
    #
    if not vids and isinstance(vids, list):
        return []
    #
    # default retry when none specificed
    #
    if retry is None:
        retry = DEFAULT_RETRY
    #
    # lookaside determination/setup. Three possible values:
    #
    #   None  - No lookup currently in progress
    #   False - Lookup in progress but first order
    #   True  - Second order lookup in progress, do not
    #           initiate a recursive lookup.
    #
    tlb = 'tlb-%s' % object
    val = coro.get_local(tlb)

    if val is None:
        val = False
    elif not val:
        val = True
    else:
        raise LookAside((tlb, val))

    look = (isinstance(vids, (list, tuple)) and [vids] or [[vids]])[0]
    data = {
        'tlb':     (tlb, val),
        'slave':   ('slave-read', slave_read()),
        'source':  socket.gethostname(), 
        'command': command,
        'args':    args,
        'kwargs':  kwargs}
    retry += 1

    results = map(lambda i: None, xrange(len(look)))
    pending = {}
    #
    # quick pass on empty lookup set.
    #
    if not look:
        return results
    #
    # create a dictionary of pending vector elements to result
    # array offsets, de-duplicate the lookup vector, order is
    # no longer imporatant since order is now maintained in the
    # pending dictionary
    #
    filter(
        lambda i: pending.setdefault(i[0], set([])).add(i[1]),
        zip(look, xrange(len(look))))
    #
    # process blank requests
    #
    for pos in pending.pop(BLANK_TOKEN, []):
        results[pos] = [{}]
    #
    # process remaining retry number of times.
    #
    while retry and pending:
        retry -= 1
        lookup = pending.keys()
        values = notifier.rpcs(
            object,    lookup,    'execute', data,
            timeout = timeout,
            local   = not val)
        if not values:
            continue
        #
        # map values to correct result location
        #
        for i in xrange(len(lookup)):
            if not values[i]:
                push = pending.get(lookup[i]) 
            else:
                push = pending.pop(lookup[i])
            for pos in push:
                results[pos] = values[i]

    #
    # look for absence of any results, raize an error even if only
    # one element is in error
    #
    errors = filter(lambda i: not i, results)
    if errors:
        #
        # since we can only raise one type of error, decide based on
        # the type of the first list element in the error set.
        # (empty list is a server error, none is a client error
        #
        if errors[0] is None:
            raise ClientError(look, data, errors)
        else:
            raise ServerError(look, data, errors)
    #
    # if we're not looking for raw data (function called with raw=True) then
    # strip out all but the first result and _unwrap it. otherwise just
    # _unwrap all the results and return them.
    #
    if not raw:
        results = map(lambda i: _unwrap((i and [i[0]] or [None])[0]), results)
    else:
        results = map(lambda i: map(_unwrap, i), results)
    #
    # when request is for a single ID and not a list of IDs rip the
    # result to match the request.
    #
    if not isinstance(vids, list):
        results = results[0]

    return results
dataset/ETHPy150Open slideinc/notifier/notifier/access.py/execute/original