Signaling support with Blinker integration

This commit is contained in:
Hyunjun Kim 2017-01-11 17:20:48 +09:00
parent bef34d66f5
commit 39e8a2b99f
4 changed files with 43 additions and 0 deletions

27
docs/signals.md Normal file
View File

@ -0,0 +1,27 @@
# Signals
Signals allow you to send notifications to multiple subscribers when the specific event occured.
Signaling is provided by [Blinker](http://pythonhosted.org/blinker/) library and
Sanic has few built-in signals:
* `request_started`: Sent when the request processing has started.
* `request_finished`: Sent when the request processing has finished.
## Examples
```python
from sanic.signals import request_started
import my_realtime_stat
app = Sanic(__name__)
@request_started.connect
def collect_stats(request):
my_realtime_stat.incoming_requests.incr(request.url)
@request_finished.connect
def count_errors(response):
if response.status != 200:
my_realtime_stat.error_responses.incr(response.status)
```

View File

@ -2,3 +2,5 @@ httptools
ujson ujson
uvloop uvloop
aiofiles aiofiles
multidict
blinker

View File

@ -13,6 +13,7 @@ from .log import log
from .response import HTTPResponse from .response import HTTPResponse
from .router import Router from .router import Router
from .server import serve, HttpProtocol from .server import serve, HttpProtocol
from .signals import request_started, request_finished
from .static import register as static_register from .static import register as static_register
from .exceptions import ServerError from .exceptions import ServerError
from socket import socket, SOL_SOCKET, SO_REUSEADDR from socket import socket, SOL_SOCKET, SO_REUSEADDR
@ -176,6 +177,8 @@ class Sanic:
:return: Nothing :return: Nothing
""" """
try: try:
request_started.send(request)
# -------------------------------------------- # # -------------------------------------------- #
# Request Middleware # Request Middleware
# -------------------------------------------- # # -------------------------------------------- #
@ -239,6 +242,7 @@ class Sanic:
response = HTTPResponse( response = HTTPResponse(
"An error occurred while handling an error") "An error occurred while handling an error")
request_finished.send(response)
response_callback(response) response_callback(response)
# -------------------------------------------------------------------- # # -------------------------------------------------------------------- #

10
sanic/signals.py Normal file
View File

@ -0,0 +1,10 @@
from blinker import Namespace
__all__ = ('request_started', 'request_finished')
_signals = Namespace()
signal = _signals.signal
request_started = signal('request-started')
request_finished = signal('request-finished')