Merge pull request #1393 from ashleysommer/pickleable-app-blueprint
Fix pickling blueprints Fixes #1392
This commit is contained in:
commit
df0e3de911
@ -5,7 +5,7 @@ from sanic.views import CompositionView
|
|||||||
|
|
||||||
|
|
||||||
FutureRoute = namedtuple(
|
FutureRoute = namedtuple(
|
||||||
"Route",
|
"FutureRoute",
|
||||||
[
|
[
|
||||||
"handler",
|
"handler",
|
||||||
"uri",
|
"uri",
|
||||||
@ -17,11 +17,15 @@ FutureRoute = namedtuple(
|
|||||||
"name",
|
"name",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
FutureListener = namedtuple("Listener", ["handler", "uri", "methods", "host"])
|
FutureListener = namedtuple(
|
||||||
FutureMiddleware = namedtuple("Route", ["middleware", "args", "kwargs"])
|
"FutureListener", ["handler", "uri", "methods", "host"]
|
||||||
FutureException = namedtuple("Route", ["handler", "args", "kwargs"])
|
)
|
||||||
|
FutureMiddleware = namedtuple(
|
||||||
|
"FutureMiddleware", ["middleware", "args", "kwargs"]
|
||||||
|
)
|
||||||
|
FutureException = namedtuple("FutureException", ["handler", "args", "kwargs"])
|
||||||
FutureStatic = namedtuple(
|
FutureStatic = namedtuple(
|
||||||
"Route", ["uri", "file_or_directory", "args", "kwargs"]
|
"FutureStatic", ["uri", "file_or_directory", "args", "kwargs"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import multiprocessing
|
import multiprocessing
|
||||||
import random
|
import random
|
||||||
import signal
|
import signal
|
||||||
|
import pickle
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from sanic.testing import HOST, PORT
|
from sanic.testing import HOST, PORT
|
||||||
|
from sanic.response import text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
@ -27,3 +29,54 @@ def test_multiprocessing(app):
|
|||||||
app.run(HOST, PORT, workers=num_workers)
|
app.run(HOST, PORT, workers=num_workers)
|
||||||
|
|
||||||
assert len(process_list) == num_workers
|
assert len(process_list) == num_workers
|
||||||
|
|
||||||
|
|
||||||
|
def test_multiprocessing_with_blueprint(app):
|
||||||
|
from sanic import Blueprint
|
||||||
|
# Selects a number at random so we can spot check
|
||||||
|
num_workers = random.choice(range(2, multiprocessing.cpu_count() * 2 + 1))
|
||||||
|
process_list = set()
|
||||||
|
|
||||||
|
def stop_on_alarm(*args):
|
||||||
|
for process in multiprocessing.active_children():
|
||||||
|
process_list.add(process.pid)
|
||||||
|
process.terminate()
|
||||||
|
|
||||||
|
signal.signal(signal.SIGALRM, stop_on_alarm)
|
||||||
|
signal.alarm(3)
|
||||||
|
|
||||||
|
bp = Blueprint('test_text')
|
||||||
|
app.blueprint(bp)
|
||||||
|
app.run(HOST, PORT, workers=num_workers)
|
||||||
|
|
||||||
|
assert len(process_list) == num_workers
|
||||||
|
|
||||||
|
|
||||||
|
# this function must be outside a test function so that it can be
|
||||||
|
# able to be pickled (local functions cannot be pickled).
|
||||||
|
def handler(request):
|
||||||
|
return text('Hello')
|
||||||
|
|
||||||
|
# Muliprocessing on Windows requires app to be able to be pickled
|
||||||
|
@pytest.mark.parametrize('protocol', [3, 4])
|
||||||
|
def test_pickle_app(app, protocol):
|
||||||
|
app.route('/')(handler)
|
||||||
|
p_app = pickle.dumps(app, protocol=protocol)
|
||||||
|
up_p_app = pickle.loads(p_app)
|
||||||
|
assert up_p_app
|
||||||
|
request, response = app.test_client.get('/')
|
||||||
|
assert response.text == 'Hello'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('protocol', [3, 4])
|
||||||
|
def test_pickle_app_with_bp(app, protocol):
|
||||||
|
from sanic import Blueprint
|
||||||
|
bp = Blueprint('test_text')
|
||||||
|
bp.route('/')(handler)
|
||||||
|
app.blueprint(bp)
|
||||||
|
p_app = pickle.dumps(app, protocol=protocol)
|
||||||
|
up_p_app = pickle.loads(p_app)
|
||||||
|
assert up_p_app
|
||||||
|
request, response = app.test_client.get('/')
|
||||||
|
assert app.is_request_stream is False
|
||||||
|
assert response.text == 'Hello'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user