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 10, 2020
1 parent e2eac21 commit 0f5f3b3
Showing 1 changed file with 42 additions and 2 deletions.
44 changes: 42 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,9 @@ 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_obj = LocalChalice(app_obj)
casted_local_app_obj = cast(Chalice, local_app_obj)
return LocalDevServer(casted_local_app_obj, config, host, port)


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


class LocalChalice(object):
def __init__(self, chalice):
# type: (Chalice) -> None
self._current_request_lookup = {} # type: Dict[int, Optional[Request]]
self._chalice = chalice

@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

def __getattr__(self, name):
# type: (str) -> Any
return getattr(self._chalice, name)

def __call__(self, *args, **kwargs):
# type: (Any, Any) -> Any
return self._chalice(*args, **kwargs)

0 comments on commit 0f5f3b3

Please sign in to comment.