def _getConnectionFromIdentifiers(self, identifiers, timeout): """Wait up to `timeout` seconds for at least one connection from `identifiers`. Returns a `Deferred` which will fire with a list of random connections to each client. Only one connection per client will be returned. The public interface to this method is `getClientFromIdentifiers`. """ matched_connections = [] for ident in identifiers: conns = list(self.connections[ident]) if len(conns) > 0: matched_connections.append(random.choice(conns)) if len(matched_connections) > 0: return defer.succeed(matched_connections) else: # No connections for any of the identifiers. Wait for at least one # connection to appear during the timeout. def discard_all(waiters, identifiers, d): """Discard all defers in the waiters for all identifiers.""" for ident in identifiers: waiters[ident].discard(d) def cb_conn_list(conn): """Convert connection into a list.""" return [conn] d = deferWithTimeout(timeout) d.addBoth(callOut, discard_all, self.waiters, identifiers, d) d.addCallback(cb_conn_list) for ident in identifiers: self.waiters[ident].add(d) return d
def discover_projects(client): return deferWithTimeout( timeout, client, DiscoverPodProjects, type=pod_type, context=context, )
def discover(client): return deferWithTimeout(timeout, client, DiscoverPod, type=pod_type, context=context, pod_id=pod_id, name=name)
def call_proc(cmd, env, try_num, timeout): log.debug("[try:{try_num}] Service monitor executing cmd: {cmd()}", try_num=try_num, cmd=lambda: ' '.join(cmd)) d = deferWithTimeout(timeout, getProcessOutputAndValue, cmd[0], cmd[1:], env=env) d.addCallback(log_code, cmd, try_num) return d.addCallback(decode)
def _getConnectionFor(self, ident, timeout): """Wait up to `timeout` seconds for a connection for `ident`. Returns a `Deferred` which will fire with the connection, or fail with `CancelledError`. The public interface to this method is `getClientFor`. """ conns = list(self.connections[ident]) if len(conns) == 0: waiters = self.waiters[ident] d = deferWithTimeout(timeout) d.addBoth(callOut, waiters.discard, d) waiters.add(d) return d else: connection = random.choice(conns) return defer.succeed(connection)
def __call__(self, cmd, *args, **kwargs): """Call a remote RPC method. This is how the client is normally used. :note: Though the call signature shows positional arguments, their use is an error. They're in the signature is so this method can detect them and provide a better error message than that from Python. Python's error message when arguments don't match the call's signature is not great at best, but it also makes it hard to figure out the receiver when the `TypeError` is raised in a different stack from the caller's, e.g. when calling into the Twisted reactor from a thread. :param cmd: The `amp.Command` child class representing the remote method to be invoked. :param kwargs: Any parameters to the remote method. Only keyword arguments are accepted. :return: A deferred result. Call its `wait` method (with a timeout in seconds) to block on the call's completion. """ if len(args) != 0: receiver_name = "%s.%s" % ( self.__module__, self.__class__.__name__, ) raise TypeError( "%s called with %d positional arguments, %r, but positional " "arguments are not supported. Usage: client(command, arg1=" "value1, ...)" % (receiver_name, len(args), args) ) timeout = kwargs.pop("_timeout", undefined) if timeout is undefined: timeout = 120 # 2 minutes if timeout is None or timeout <= 0: return self._conn.callRemote(cmd, **kwargs) else: return deferWithTimeout( timeout, self._conn.callRemote, cmd, **kwargs )