Skip to content

Commit

Permalink
changes to make app.current_request thread safe when running chalice …
Browse files Browse the repository at this point in the history
…locally

- fixes race conditions that can occur when chalice is being run locally
  and it handling multiple concurrent requests
  • Loading branch information
Joel Tetrault committed Mar 6, 2020
1 parent b79470d commit ef3ce1f
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions chalice/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@
from six.moves.BaseHTTPServer import HTTPServer
from six.moves.BaseHTTPServer import BaseHTTPRequestHandler
from six.moves.socketserver import ThreadingMixIn
from typing import List, Any, Dict, Tuple, Callable, Optional, Union # noqa
from typing import (
List,
Any,
Dict,
Tuple,
Callable,
Optional,
Union,
cast,
) # noqa

from chalice.app import Chalice # noqa
from chalice.app import CORSConfig # noqa
Expand Down Expand Up @@ -47,7 +56,10 @@ def time(self):

def create_local_server(app_obj, config, host, port):
# type: (Chalice, Config, str, int) -> LocalDevServer
return LocalDevServer(app_obj, config, host, port)
local_app_opj = cast(LocalChalice, app_obj) # type: LocalChalice
local_app_opj.__class__ = LocalChalice
local_app_opj.initialize_current_request_lookup()
return LocalDevServer(local_app_opj, config, host, port)


class LocalARNBuilder(object):
Expand Down Expand Up @@ -661,3 +673,28 @@ def shutdown(self):
# type: () -> None
if self._server is not None:
self._server.shutdown()


class LocalChalice(Chalice):
def __init__(self, *args, **kwargs):
# type: (Any, Any) -> None
self._current_request_lookup = {} # type: Dict[int, Optional[Request]]
super(LocalChalice, self).__init__(*args, **kwargs)

def initialize_current_request_lookup(self):
# type: () -> None
self._current_request_lookup = {}

@property
def current_request(self): # noqa
# type: () -> Optional[Request]
thread_id = threading.current_thread().ident
assert thread_id is not None
return self._current_request_lookup.get(thread_id, None)

@current_request.setter
def current_request(self, value): # noqa
# type: (Optional[Request]) -> None
thread_id = threading.current_thread().ident
assert thread_id is not None
self._current_request_lookup[thread_id] = value

0 comments on commit ef3ce1f

Please sign in to comment.