示例#1
0
def test_timeout_in_call(broker):
    timeout = 1
    delay = timeout + 0.5
    with Timer() as t:
        with pytest.raises(errors.Timeout) as exc:
            broker.execute("sleep", delay, timeout=timeout).result
    assert exc.value.args[0].endswith("/services/sleep")
    assert t.elapsed < delay
    assert t.elapsed > timeout
示例#2
0
    def __init__(self, http_session, service, args, kwargs, context):
        self.http_session = http_session
        self.timeout = check_timeout(
            kwargs.pop("timeout", self.default_timeout))
        self.args = args
        self.kwargs = dict(kwargs)
        # local_only = self.kwargs.pop("local_only", False)
        # self.url = registry.instance().service_url(service, local_only=local_only)
        self.url = registry.instance().service_url(service)
        self.id = core.call_id()
        if context is None:
            context = ClientContext(self.id)
        self.context = context
        self.timer = Timer()

        self._response = None
        self._thread = t = threading.Thread(target=self._runner)
        t.setDaemon(True)
        t.start()
示例#3
0
 def from_dict(cls, d):
     ret = cls(d["task"])
     ret._timers = {k: Timer.from_dict(v) for k, v in d["timers"].items()}
     ret._kids = [cls.from_dict(k) for k in d["kids"]]
     ret._notes = d["notes"]
     ret._host = d["host"]
     ret._pid = d["pid"]
     if "start" in d:
         ret._start = d["start"]
     if "stop" in d:
         ret._stop = d["stop"]
     return ret
示例#4
0
def test_default_timeout_in_call(broker):
    default_timeout = client.get_default_timeout()
    client.Result._default_timeout = 1
    delay = client.Result._default_timeout + 0.5

    try:
        with Timer() as t:
            with pytest.raises(errors.Timeout) as exc:
                broker.execute("sleep", delay).result
        assert exc.value.args[0].endswith("/services/sleep")
        assert t.elapsed < delay
        assert t.elapsed > client.Result._default_timeout
    finally:
        client.Result._default_timeout = default_timeout
示例#5
0
def test_execute_sync(broker):
    """Calls to ``servicelib.client.Broker.execute()`` are asynchronous

    Accessing the ``result`` or ``metadata`` fields of the returned value,
    however, are synchronous operations.

    """
    delay = 1

    with Timer() as t_complete:
        with Timer() as t_submit:
            res = broker.execute("sleep", delay)
        assert res.result

    assert t_submit.elapsed < delay
    assert t_complete.elapsed > delay

    with Timer() as t_complete:
        with Timer() as t_submit:
            res = broker.execute("sleep", delay)
        assert res.metadata

    assert t_submit.elapsed < delay
    assert t_complete.elapsed > delay
示例#6
0
 def from_http_headers(cls, h):
     ret = cls(h["task"])
     ret._timers = {
         k: Timer.from_dict(v)
         for k, v in json.loads(h["timers"]).items()
     }
     ret._kids = [cls.from_dict(k) for k in json.loads(h["kids"])]
     ret._host = h["host"]
     ret._pid = int(h["pid"])
     ret._start = float(h["start"])
     ret._stop = float(h["stop"])
     ret._notes = {
         k[len("note-"):]: json.loads(v)
         for (k, v) in h.items() if k.startswith("note-")
     }
     return ret
示例#7
0
def test_timeout_in_wait(broker):
    timeout = 1
    delay = timeout + 0.5

    res = broker.execute("sleep", delay)

    # The first call to `wait()` times out.
    with Timer() as t:
        with pytest.raises(errors.Timeout) as exc:
            res.wait(timeout)
        assert exc.value.args[0].endswith("/services/sleep")
    assert t.elapsed < delay
    assert t.elapsed > timeout

    # Ensure enough time passes for the server side to complete its
    # call.
    time.sleep(delay)

    # The second one succeeds.
    res.wait(timeout)
示例#8
0
def test_parallel_requests(broker):
    """All instances of services handle requests concurrently.

    """
    w = broker.worker_info
    num_calls = (w["num_processes"] * w["num_threads"]) + 1
    delay = 2
    overhead = 1

    def sleep():
        broker.execute("sleep", delay).wait()

    calls = []
    with Timer() as t:
        for _ in range(num_calls):
            c = threading.Thread(target=sleep)
            c.start()
            calls.append(c)

        for c in calls:
            c.join()

    assert t.elapsed >= 2 * delay
    assert t.elapsed < 2 * delay + overhead
示例#9
0
class Result(object):

    log = logutils.get_logger(__name__)

    _default_timeout = None

    def __init__(self, http_session, service, args, kwargs, context):
        self.http_session = http_session
        self.timeout = check_timeout(
            kwargs.pop("timeout", self.default_timeout))
        self.args = args
        self.kwargs = dict(kwargs)
        # local_only = self.kwargs.pop("local_only", False)
        # self.url = registry.instance().service_url(service, local_only=local_only)
        self.url = registry.instance().service_url(service)
        self.id = core.call_id()
        if context is None:
            context = ClientContext(self.id)
        self.context = context
        self.timer = Timer()

        self._response = None
        self._thread = t = threading.Thread(target=self._runner)
        t.setDaemon(True)
        t.start()

    def _runner(self):
        self.timer.start()
        try:
            req = core.Request(*self.args, **self.kwargs)
            self.log.debug(
                "POST %s, headers: %s, body: %s",
                self.url,
                req.http_headers,
                req.http_body,
            )
            # XXX It's not entirely clear that `requests.Session` is thread-safe.
            res = self.http_session.post(
                self.url,
                data=req.http_body,
                headers=req.http_headers,
                timeout=self.timeout,
            )
            res = core.Response.from_http(res.status_code, res.content,
                                          res.headers)
            self.log.debug("Response: %r", res)
            self.timer.stop()
            self.context.update_metadata(res.metadata)
        except requests.Timeout as exc:
            self.log.debug("Got timeout error: %s", exc)
            res = errors.Timeout(self.url)
        except Exception as exc:
            self.log.info(
                "%r failed: %s",
                self,
                exc,
                exc_info=True,
                stack_info=True,
            )
            res = exc

        res.metadata = self.context.metadata
        self._response = res

    def wait(self, timeout=None):
        if self._response is None:
            self._thread.join(timeout=timeout)
            if timeout is not None:
                if self._thread.is_alive():
                    raise errors.Timeout(self.url)

        if isinstance(self._response, Exception):
            raise self._response

        result = self._response.value
        if isinstance(result, Exception):
            raise result

        return result, self._response.metadata

    @property
    def result(self):
        r, _ = self.wait()
        return r

    @property
    def metadata(self):
        _, m = self.wait()
        return m

    def __repr__(self):
        return "Result(%r, %r)" % (
            self.url,
            self.args,
        )

    @property
    def default_timeout(self):
        if self.__class__._default_timeout is None:
            self.__class__._default_timeout = get_default_timeout()
        return self.__class__._default_timeout
示例#10
0
 def timer(self, name):
     if name not in self._timers:
         self._timers[name] = Timer()
     return self._timers[name]