Skip to content

Commit

Permalink
Client signals get rid of trace_request_ctx as signal kw (#2560)
Browse files Browse the repository at this point in the history
* Client signals get rid of trace_request_ctx as signal kw

* Fix typo in documentation

* Renamed trace_config_ctx_class to trace_config_ctx_factory
  • Loading branch information
pfreixes authored and asvetlov committed Dec 5, 2017
1 parent 7c6f0bc commit feaf021
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 102 deletions.
6 changes: 4 additions & 2 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,11 @@ async def _request(self, method, url, *,

traces = [
Trace(
trace_config,
self,
trace_request_ctx=trace_request_ctx)
trace_config,
trace_config.trace_config_ctx(
trace_request_ctx=trace_request_ctx)
)
for trace_config in self._trace_configs
]

Expand Down
27 changes: 7 additions & 20 deletions aiohttp/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TraceConfig:
"""First-class used to trace requests launched via ClientSession
objects."""

def __init__(self, trace_config_ctx_class=SimpleNamespace):
def __init__(self, trace_config_ctx_factory=SimpleNamespace):
self._on_request_start = Signal(self)
self._on_request_end = Signal(self)
self._on_request_exception = Signal(self)
Expand All @@ -25,11 +25,12 @@ def __init__(self, trace_config_ctx_class=SimpleNamespace):
self._on_dns_cache_hit = Signal(self)
self._on_dns_cache_miss = Signal(self)

self._trace_config_ctx_class = trace_config_ctx_class
self._trace_config_ctx_factory = trace_config_ctx_factory

def trace_config_ctx(self):
def trace_config_ctx(self, trace_request_ctx=None):
""" Return a new trace_config_ctx instance """
return self._trace_config_ctx_class()
return self._trace_config_ctx_factory(
trace_request_ctx=trace_request_ctx)

def freeze(self):
self._on_request_start.freeze()
Expand Down Expand Up @@ -103,18 +104,16 @@ class Trace:
""" Internal class used to keep together the main dependencies used
at the moment of send a signal."""

def __init__(self, trace_config, session, trace_request_ctx=None):
def __init__(self, session, trace_config, trace_config_ctx):
self._trace_config = trace_config
self._trace_config_ctx = self._trace_config.trace_config_ctx()
self._trace_request_ctx = trace_request_ctx
self._trace_config_ctx = trace_config_ctx
self._session = session

async def send_request_start(self, *args, **kwargs):
return await self._trace_config.on_request_start.send(
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -123,7 +122,6 @@ async def send_request_end(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -132,7 +130,6 @@ async def send_request_exception(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -141,7 +138,6 @@ async def send_request_redirect(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -150,7 +146,6 @@ async def send_connection_queued_start(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -159,7 +154,6 @@ async def send_connection_queued_end(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -168,7 +162,6 @@ async def send_connection_create_start(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -177,7 +170,6 @@ async def send_connection_create_end(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -186,7 +178,6 @@ async def send_connection_reuseconn(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -195,7 +186,6 @@ async def send_dns_resolvehost_start(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -204,7 +194,6 @@ async def send_dns_resolvehost_end(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -213,7 +202,6 @@ async def send_dns_cache_hit(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)

Expand All @@ -222,6 +210,5 @@ async def send_dns_cache_miss(self, *args, **kwargs):
self._session,
self._trace_config_ctx,
*args,
trace_request_ctx=self._trace_request_ctx,
**kwargs
)
25 changes: 14 additions & 11 deletions docs/client_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,10 @@ disabled. The following snippet shows how the start and the end
signals of a request flow can be followed::

async def on_request_start(
session, trace_config_ctx, method,
host, port, headers, request_trace_config_ctx=None):
session, trace_config_ctx, method, host, port, headers):
print("Starting request")

async def on_request_end(session, trace_config_ctx, resp,
request_trace_config_ctx=None):
async def on_request_end(session, trace_config_ctx, resp):
print("Ending request")

trace_config = aiohttp.TraceConfig()
Expand Down Expand Up @@ -253,25 +251,30 @@ share the state through to the different signals that belong to the
same request and to the same :class:`TraceConfig` class, perhaps::

async def on_request_start(
session, trace_config_ctx, method, host, port, headers,
trace_request_ctx=None):
session, trace_config_ctx, method, host, port, headers):
trace_config_ctx.start = session.loop.time()

async def on_request_end(
session, trace_config_ctx, resp, trace_request_ctx=None):
async def on_request_end(session, trace_config_ctx, resp):
elapsed = session.loop.time() - trace_config_ctx.start
print("Request took {}".format(elapsed))


The ``trace_config_ctx`` param is by default a
:class:`SimpleNampespace` that is initialized at the beginning of the
request flow. However, the factory used to create this object can be
overwritten using the ``trace_config_ctx_class`` constructor param of
overwritten using the ``trace_config_ctx_factory`` constructor param of
the :class:`TraceConfig` class.

The ``trace_request_ctx`` param can given at the beginning of the
request execution and will be passed as a keyword argument for all of
the signals, as the following snippet shows::
request execution, accepted by all of the HTTP verbs, and will be
passed as a keyword argument for the ``trace_config_ctx_factory``
factory. This param is useful to pass data that is only available at
request time, perhaps::

async def on_request_start(
session, trace_config_ctx, method, host, port, headers):
print(trace_config_ctx.trace_request_ctx)


session.get('http://example.com/some/redirect/',
trace_request_ctx={'foo': 'bar'})
Expand Down
6 changes: 3 additions & 3 deletions docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ The client session supports the context manager protocol for self closing.

.. versionadded:: 2.3

:param trace_request_ctx: Object used to give as a kw param for the all
signals triggered by the ongoing request and for all :class:`TraceConfig`
configured. Default passes a None value.
:param trace_request_ctx: Object used to give as a kw param for each new
:class:`TraceConfig` object instantiated, used to give information to the
tracers that is only available at request time.

.. versionadded:: 3.0

Expand Down
9 changes: 6 additions & 3 deletions docs/tracing_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ Trace config is the configuration object used to trace requests launched by
a Client session object using different events related to different parts of
the request flow.

.. class:: TraceConfig(trace_config_ctx_class=SimpleNamespace)
.. class:: TraceConfig(trace_config_ctx_factory=SimpleNamespace)

:param trace_config_ctx_class: factory used to create trace contexts,
:param trace_config_ctx_factory: factory used to create trace contexts,
default class used :class:`SimpleNamespace`

.. method:: trace_config_ctx()
.. method:: trace_config_ctx(trace_request_ctx=None)

:param trace_request_ctx: Will be used to pass as a kw for the
``trace_config_ctx_factory``.

Return a new trace context.

Expand Down
11 changes: 4 additions & 7 deletions tests/test_client_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ async def test_request_tracing(loop):
on_request_end = mock.Mock(side_effect=asyncio.coroutine(mock.Mock()))

trace_config = aiohttp.TraceConfig(
trace_config_ctx_class=mock.Mock(return_value=trace_config_ctx)
trace_config_ctx_factory=mock.Mock(return_value=trace_config_ctx)
)
trace_config.on_request_start.append(on_request_start)
trace_config.on_request_end.append(on_request_end)
Expand All @@ -480,8 +480,7 @@ async def test_request_tracing(loop):
trace_config_ctx,
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
trace_request_ctx=trace_request_ctx
CIMultiDict()
)

on_request_end.assert_called_once_with(
Expand All @@ -490,8 +489,7 @@ async def test_request_tracing(loop):
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
resp,
trace_request_ctx=trace_request_ctx
resp
)
assert not on_request_redirect.called

Expand Down Expand Up @@ -528,8 +526,7 @@ async def test_request_tracing_exception(loop):
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
error,
trace_request_ctx=mock.ANY
error
)
assert not on_request_end.called

Expand Down
Loading

0 comments on commit feaf021

Please sign in to comment.