We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Heartbeat max timeout
Let's make sure the heartbeat times out before 30 seconds. Otherwise uWSGI hara kiris the web head and we don't have a chance to send back the result of the heartbeat where it tells us which backend fails.

I suggest 15 seconds max by defaut + an option.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kinto/core/__init__.py`
Content:
```
1 """Main entry point
2 """
3 import pkg_resources
4 
5 from cornice import Service as CorniceService
6 from pyramid.settings import aslist
7 
8 from kinto.core import authentication
9 from kinto.core import errors
10 from kinto.core import events
11 from kinto.core.initialization import (  # NOQA
12     initialize, install_middlewares,
13     load_default_settings)
14 from kinto.core.utils import (
15     follow_subrequest, current_service, current_resource_name)
16 from kinto.core.logs import logger
17 
18 
19 # Module version, as defined in PEP-0396.
20 __version__ = pkg_resources.get_distribution('kinto').version  # FIXME?
21 
22 
23 DEFAULT_SETTINGS = {
24     'backoff': None,
25     'batch_max_requests': 25,
26     'cache_backend': '',
27     'cache_url': '',
28     'cache_pool_size': 25,
29     'cache_prefix': '',
30     'cors_origins': '*',
31     'cors_max_age_seconds': 3600,
32     'eos': None,
33     'eos_message': None,
34     'eos_url': None,
35     'error_info_link': 'https://github.com/Kinto/kinto/issues/',
36     'http_host': None,
37     'http_scheme': None,
38     'id_generator': 'kinto.core.storage.generators.UUID4',
39     'includes': '',
40     'initialization_sequence': (
41         'kinto.core.initialization.setup_request_bound_data',
42         'kinto.core.initialization.setup_json_serializer',
43         'kinto.core.initialization.setup_logging',
44         'kinto.core.initialization.setup_storage',
45         'kinto.core.initialization.setup_permission',
46         'kinto.core.initialization.setup_cache',
47         'kinto.core.initialization.setup_requests_scheme',
48         'kinto.core.initialization.setup_version_redirection',
49         'kinto.core.initialization.setup_deprecation',
50         'kinto.core.initialization.setup_authentication',
51         'kinto.core.initialization.setup_backoff',
52         'kinto.core.initialization.setup_statsd',
53         'kinto.core.initialization.setup_listeners',
54         'kinto.core.events.setup_transaction_hook',
55     ),
56     'event_listeners': '',
57     'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',
58     'newrelic_config': None,
59     'newrelic_env': 'dev',
60     'paginate_by': None,
61     'permission_backend': '',
62     'permission_url': '',
63     'permission_pool_size': 25,
64     'profiler_dir': '/tmp',
65     'profiler_enabled': False,
66     'project_docs': '',
67     'project_name': '',
68     'project_version': '',
69     'readonly': False,
70     'retry_after_seconds': 30,
71     'statsd_prefix': 'kinto.core',
72     'statsd_url': None,
73     'storage_backend': '',
74     'storage_url': '',
75     'storage_max_fetch_size': 10000,
76     'storage_pool_size': 25,
77     'tm.annotate_user': False,  # Do annotate transactions with the user-id.
78     'transaction_per_request': True,
79     'userid_hmac_secret': '',
80     'version_prefix_redirect_enabled': True,
81     'trailing_slash_redirect_enabled': True,
82     'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',
83     'multiauth.policies': 'basicauth',
84     'multiauth.policy.basicauth.use': ('kinto.core.authentication.'
85                                        'BasicAuthAuthenticationPolicy'),
86     'multiauth.authorization_policy': ('kinto.core.authorization.'
87                                        'AuthorizationPolicy')
88 }
89 
90 
91 class Service(CorniceService):
92     """Subclass of the default cornice service.
93 
94     This is useful in order to attach specific behaviours without monkey
95     patching the default cornice service (which would impact other uses of it)
96     """
97     default_cors_headers = ('Backoff', 'Retry-After', 'Alert',
98                             'Content-Length')
99 
100     def error_handler(self, error):
101         return errors.json_error_handler(error)
102 
103     @classmethod
104     def init_from_settings(cls, settings):
105         cls.cors_origins = tuple(aslist(settings['cors_origins']))
106         cors_max_age = settings['cors_max_age_seconds']
107         cls.cors_max_age = int(cors_max_age) if cors_max_age else None
108 
109 
110 def includeme(config):
111     settings = config.get_settings()
112 
113     # Heartbeat registry.
114     config.registry.heartbeats = {}
115 
116     # Public settings registry.
117     config.registry.public_settings = {'batch_max_requests', 'readonly'}
118 
119     # Directive to declare arbitrary API capabilities.
120     def add_api_capability(config, identifier, description="", url="", **kw):
121         existing = config.registry.api_capabilities.get(identifier)
122         if existing:
123             error_msg = "The '%s' API capability was already registered (%s)."
124             raise ValueError(error_msg % (identifier, existing))
125 
126         capability = dict(description=description, url=url, **kw)
127         config.registry.api_capabilities[identifier] = capability
128 
129     config.add_directive('add_api_capability', add_api_capability)
130     config.registry.api_capabilities = {}
131 
132     # Resource events helpers.
133     config.add_request_method(events.get_resource_events,
134                               name='get_resource_events')
135     config.add_request_method(events.notify_resource_event,
136                               name='notify_resource_event')
137 
138     # Setup cornice.
139     config.include("cornice")
140 
141     # Per-request transaction.
142     config.include("pyramid_tm")
143 
144     # Add CORS settings to the base kinto.core Service class.
145     Service.init_from_settings(settings)
146 
147     # Setup components.
148     for step in aslist(settings['initialization_sequence']):
149         step_func = config.maybe_dotted(step)
150         step_func(config)
151 
152     # Custom helpers.
153     config.add_request_method(follow_subrequest)
154     config.add_request_method(authentication.prefixed_userid, property=True)
155     config.add_request_method(lambda r: {'id': r.prefixed_userid},
156                               name='get_user_info')
157     config.add_request_method(current_resource_name, reify=True)
158     config.add_request_method(current_service, reify=True)
159     config.commit()
160 
161     # Include plugins after init, unlike pyramid includes.
162     includes = aslist(settings['includes'])
163     for app in includes:
164         config.include(app)
165 
166     # # Show settings to output.
167     # for key, value in settings.items():
168     #     logger.info('Using %s = %s' % (key, value))
169 
170     # Scan views.
171     config.scan("kinto.core.views")
172 
173     # Give sign of life.
174     msg = "%(project_name)s %(project_version)s starting."
175     logger.info(msg % settings)
176
```

Path: `setup.py`
Content:
```
1 import platform
2 import codecs
3 import os
4 from setuptools import setup, find_packages
5 
6 here = os.path.abspath(os.path.dirname(__file__))
7 
8 def read_file(filename):
9     """Open a related file and return its content."""
10     with codecs.open(os.path.join(here, filename), encoding='utf-8') as f:
11         content = f.read()
12     return content
13 
14 README = read_file('README.rst')
15 CHANGELOG = read_file('CHANGELOG.rst')
16 CONTRIBUTORS = read_file('CONTRIBUTORS.rst')
17 
18 installed_with_pypy = platform.python_implementation() == 'PyPy'
19 
20 REQUIREMENTS = [
21     'colander',
22     'colorama',
23     'cornice >= 1.1',  # Fix cache CORS
24     'jsonschema',
25     'python-dateutil',
26     'pyramid_multiauth >= 0.8',  # User on policy selected event.
27     'pyramid_tm',
28     'redis',  # Default backend
29     'requests',
30     'six',
31     'structlog >= 16.1.0',
32     'enum34',
33     'waitress',
34 ]
35 
36 if installed_with_pypy:
37     # We install psycopg2cffi instead of psycopg2 when dealing with pypy
38     # Note: JSONB support landed after psycopg2cffi 2.7.0
39     POSTGRESQL_REQUIRES = [
40         'SQLAlchemy',
41         'psycopg2cffi>2.7.0',
42         'zope.sqlalchemy',
43     ]
44 else:
45     # ujson is not pypy compliant, as it uses the CPython C API
46     REQUIREMENTS.append('ujson >= 1.35')
47     POSTGRESQL_REQUIRES = [
48         'SQLAlchemy',
49         'psycopg2>2.5',
50         'zope.sqlalchemy',
51     ]
52 
53 DEPENDENCY_LINKS = [
54 ]
55 
56 MONITORING_REQUIRES = [
57     'raven',
58     'statsd',
59     'newrelic',
60     'werkzeug',
61 ]
62 
63 ENTRY_POINTS = {
64     'paste.app_factory': [
65         'main = kinto:main',
66     ],
67     'console_scripts': [
68         'kinto = kinto.__main__:main'
69     ],
70 }
71 
72 
73 setup(name='kinto',
74       version='3.1.1.dev0',
75       description='Kinto Web Service - Store, Sync, Share, and Self-Host.',
76       long_description=README + "\n\n" + CHANGELOG + "\n\n" + CONTRIBUTORS,
77       license='Apache License (2.0)',
78       classifiers=[
79           "Programming Language :: Python",
80           "Programming Language :: Python :: 2",
81           "Programming Language :: Python :: 2.7",
82           "Programming Language :: Python :: 3",
83           "Programming Language :: Python :: 3.4",
84           "Programming Language :: Python :: 3.5",
85           "Programming Language :: Python :: Implementation :: CPython",
86           "Programming Language :: Python :: Implementation :: PyPy",
87           "Topic :: Internet :: WWW/HTTP",
88           "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
89           "License :: OSI Approved :: Apache Software License"
90       ],
91       keywords="web sync json storage services",
92       author='Mozilla Services',
93       author_email='storage-team@mozilla.com',
94       url='https://github.com/Kinto/kinto',
95       packages=find_packages(),
96       package_data={'': ['*.rst', '*.py']},
97       include_package_data=True,
98       zip_safe=False,
99       install_requires=REQUIREMENTS,
100       extras_require={
101           'postgresql': POSTGRESQL_REQUIRES,
102           'monitoring': MONITORING_REQUIRES,
103           ":python_version=='2.7'": ["functools32"],
104       },
105       test_suite="kinto.tests",
106       dependency_links=DEPENDENCY_LINKS,
107       entry_points=ENTRY_POINTS)
108
```

Path: `kinto/core/views/heartbeat.py`
Content:
```
1 from pyramid.security import NO_PERMISSION_REQUIRED
2 
3 from kinto.core import Service
4 
5 heartbeat = Service(name="heartbeat", path='/__heartbeat__',
6                     description="Server health")
7 
8 
9 @heartbeat.get(permission=NO_PERMISSION_REQUIRED)
10 def get_heartbeat(request):
11     """Return information about server health."""
12     status = {}
13 
14     heartbeats = request.registry.heartbeats
15     for name, callable in heartbeats.items():
16         status[name] = callable(request)
17 
18     has_error = not all([v or v is None for v in status.values()])
19     if has_error:
20         request.response.status = 503
21 
22     return status
23 
24 
25 lbheartbeat = Service(name="lbheartbeat", path='/__lbheartbeat__',
26                       description="Web head health")
27 
28 
29 @lbheartbeat.get(permission=NO_PERMISSION_REQUIRED)
30 def get_lbheartbeat(request):
31     """Return successful healthy response.
32 
33     If the load-balancer tries to access this URL and fails, this means the
34     Web head is not operational and should be dropped.
35     """
36     status = {}
37     return status
38
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kinto/core/__init__.py b/kinto/core/__init__.py
--- a/kinto/core/__init__.py
+++ b/kinto/core/__init__.py
@@ -54,6 +54,7 @@
         'kinto.core.events.setup_transaction_hook',
     ),
     'event_listeners': '',
+    'heartbeat_timeout_seconds': 10,
     'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',
     'newrelic_config': None,
     'newrelic_env': 'dev',
diff --git a/kinto/core/views/heartbeat.py b/kinto/core/views/heartbeat.py
--- a/kinto/core/views/heartbeat.py
+++ b/kinto/core/views/heartbeat.py
@@ -1,7 +1,10 @@
+from concurrent.futures import ThreadPoolExecutor, wait
 from pyramid.security import NO_PERMISSION_REQUIRED
 
+from kinto import logger
 from kinto.core import Service
 
+
 heartbeat = Service(name="heartbeat", path='/__heartbeat__',
                     description="Server health")
 
@@ -11,10 +14,38 @@
     """Return information about server health."""
     status = {}
 
+    def heartbeat_check(name, func):
+        status[name] = False
+        status[name] = func(request)
+
+    # Start executing heartbeats concurrently.
     heartbeats = request.registry.heartbeats
-    for name, callable in heartbeats.items():
-        status[name] = callable(request)
+    pool = ThreadPoolExecutor(max_workers=max(1, len(heartbeats.keys())))
+    futures = []
+    for name, func in heartbeats.items():
+        future = pool.submit(heartbeat_check, name, func)
+        future.__heartbeat_name = name  # For logging purposes.
+        futures.append(future)
+
+    # Wait for the results, with timeout.
+    seconds = float(request.registry.settings['heartbeat_timeout_seconds'])
+    done, not_done = wait(futures, timeout=seconds)
+
+    # A heartbeat is supposed to return True or False, and never raise.
+    # Just in case, go though results to spot any potential exception.
+    for future in done:
+        exc = future.exception()
+        if exc is not None:
+            logger.error("%r heartbeat failed." % future.__heartbeat_name)
+            logger.error(exc)
+
+    # Log timed-out heartbeats.
+    for future in not_done:
+        name = future.__heartbeat_name
+        error_msg = "%r heartbeat has exceeded timeout of %s seconds."
+        logger.error(error_msg % (name, seconds))
 
+    # If any has failed, return a 503 error response.
     has_error = not all([v or v is None for v in status.values()])
     if has_error:
         request.response.status = 503
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -100,7 +100,7 @@
       extras_require={
           'postgresql': POSTGRESQL_REQUIRES,
           'monitoring': MONITORING_REQUIRES,
-          ":python_version=='2.7'": ["functools32"],
+          ":python_version=='2.7'": ["functools32", "futures"],
       },
       test_suite="kinto.tests",
       dependency_links=DEPENDENCY_LINKS,

{"golden_diff": "diff --git a/kinto/core/__init__.py b/kinto/core/__init__.py\n--- a/kinto/core/__init__.py\n+++ b/kinto/core/__init__.py\n@@ -54,6 +54,7 @@\n         'kinto.core.events.setup_transaction_hook',\n     ),\n     'event_listeners': '',\n+    'heartbeat_timeout_seconds': 10,\n     'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',\n     'newrelic_config': None,\n     'newrelic_env': 'dev',\ndiff --git a/kinto/core/views/heartbeat.py b/kinto/core/views/heartbeat.py\n--- a/kinto/core/views/heartbeat.py\n+++ b/kinto/core/views/heartbeat.py\n@@ -1,7 +1,10 @@\n+from concurrent.futures import ThreadPoolExecutor, wait\n from pyramid.security import NO_PERMISSION_REQUIRED\n \n+from kinto import logger\n from kinto.core import Service\n \n+\n heartbeat = Service(name=\"heartbeat\", path='/__heartbeat__',\n                     description=\"Server health\")\n \n@@ -11,10 +14,38 @@\n     \"\"\"Return information about server health.\"\"\"\n     status = {}\n \n+    def heartbeat_check(name, func):\n+        status[name] = False\n+        status[name] = func(request)\n+\n+    # Start executing heartbeats concurrently.\n     heartbeats = request.registry.heartbeats\n-    for name, callable in heartbeats.items():\n-        status[name] = callable(request)\n+    pool = ThreadPoolExecutor(max_workers=max(1, len(heartbeats.keys())))\n+    futures = []\n+    for name, func in heartbeats.items():\n+        future = pool.submit(heartbeat_check, name, func)\n+        future.__heartbeat_name = name  # For logging purposes.\n+        futures.append(future)\n+\n+    # Wait for the results, with timeout.\n+    seconds = float(request.registry.settings['heartbeat_timeout_seconds'])\n+    done, not_done = wait(futures, timeout=seconds)\n+\n+    # A heartbeat is supposed to return True or False, and never raise.\n+    # Just in case, go though results to spot any potential exception.\n+    for future in done:\n+        exc = future.exception()\n+        if exc is not None:\n+            logger.error(\"%r heartbeat failed.\" % future.__heartbeat_name)\n+            logger.error(exc)\n+\n+    # Log timed-out heartbeats.\n+    for future in not_done:\n+        name = future.__heartbeat_name\n+        error_msg = \"%r heartbeat has exceeded timeout of %s seconds.\"\n+        logger.error(error_msg % (name, seconds))\n \n+    # If any has failed, return a 503 error response.\n     has_error = not all([v or v is None for v in status.values()])\n     if has_error:\n         request.response.status = 503\ndiff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -100,7 +100,7 @@\n       extras_require={\n           'postgresql': POSTGRESQL_REQUIRES,\n           'monitoring': MONITORING_REQUIRES,\n-          \":python_version=='2.7'\": [\"functools32\"],\n+          \":python_version=='2.7'\": [\"functools32\", \"futures\"],\n       },\n       test_suite=\"kinto.tests\",\n       dependency_links=DEPENDENCY_LINKS,\n", "issue": "Heartbeat max timeout\nLet's make sure the heartbeat times out before 30 seconds. Otherwise uWSGI hara kiris the web head and we don't have a chance to send back the result of the heartbeat where it tells us which backend fails.\n\nI suggest 15 seconds max by defaut + an option.\n\n", "before_files": [{"content": "\"\"\"Main entry point\n\"\"\"\nimport pkg_resources\n\nfrom cornice import Service as CorniceService\nfrom pyramid.settings import aslist\n\nfrom kinto.core import authentication\nfrom kinto.core import errors\nfrom kinto.core import events\nfrom kinto.core.initialization import (  # NOQA\n    initialize, install_middlewares,\n    load_default_settings)\nfrom kinto.core.utils import (\n    follow_subrequest, current_service, current_resource_name)\nfrom kinto.core.logs import logger\n\n\n# Module version, as defined in PEP-0396.\n__version__ = pkg_resources.get_distribution('kinto').version  # FIXME?\n\n\nDEFAULT_SETTINGS = {\n    'backoff': None,\n    'batch_max_requests': 25,\n    'cache_backend': '',\n    'cache_url': '',\n    'cache_pool_size': 25,\n    'cache_prefix': '',\n    'cors_origins': '*',\n    'cors_max_age_seconds': 3600,\n    'eos': None,\n    'eos_message': None,\n    'eos_url': None,\n    'error_info_link': 'https://github.com/Kinto/kinto/issues/',\n    'http_host': None,\n    'http_scheme': None,\n    'id_generator': 'kinto.core.storage.generators.UUID4',\n    'includes': '',\n    'initialization_sequence': (\n        'kinto.core.initialization.setup_request_bound_data',\n        'kinto.core.initialization.setup_json_serializer',\n        'kinto.core.initialization.setup_logging',\n        'kinto.core.initialization.setup_storage',\n        'kinto.core.initialization.setup_permission',\n        'kinto.core.initialization.setup_cache',\n        'kinto.core.initialization.setup_requests_scheme',\n        'kinto.core.initialization.setup_version_redirection',\n        'kinto.core.initialization.setup_deprecation',\n        'kinto.core.initialization.setup_authentication',\n        'kinto.core.initialization.setup_backoff',\n        'kinto.core.initialization.setup_statsd',\n        'kinto.core.initialization.setup_listeners',\n        'kinto.core.events.setup_transaction_hook',\n    ),\n    'event_listeners': '',\n    'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',\n    'newrelic_config': None,\n    'newrelic_env': 'dev',\n    'paginate_by': None,\n    'permission_backend': '',\n    'permission_url': '',\n    'permission_pool_size': 25,\n    'profiler_dir': '/tmp',\n    'profiler_enabled': False,\n    'project_docs': '',\n    'project_name': '',\n    'project_version': '',\n    'readonly': False,\n    'retry_after_seconds': 30,\n    'statsd_prefix': 'kinto.core',\n    'statsd_url': None,\n    'storage_backend': '',\n    'storage_url': '',\n    'storage_max_fetch_size': 10000,\n    'storage_pool_size': 25,\n    'tm.annotate_user': False,  # Do annotate transactions with the user-id.\n    'transaction_per_request': True,\n    'userid_hmac_secret': '',\n    'version_prefix_redirect_enabled': True,\n    'trailing_slash_redirect_enabled': True,\n    'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',\n    'multiauth.policies': 'basicauth',\n    'multiauth.policy.basicauth.use': ('kinto.core.authentication.'\n                                       'BasicAuthAuthenticationPolicy'),\n    'multiauth.authorization_policy': ('kinto.core.authorization.'\n                                       'AuthorizationPolicy')\n}\n\n\nclass Service(CorniceService):\n    \"\"\"Subclass of the default cornice service.\n\n    This is useful in order to attach specific behaviours without monkey\n    patching the default cornice service (which would impact other uses of it)\n    \"\"\"\n    default_cors_headers = ('Backoff', 'Retry-After', 'Alert',\n                            'Content-Length')\n\n    def error_handler(self, error):\n        return errors.json_error_handler(error)\n\n    @classmethod\n    def init_from_settings(cls, settings):\n        cls.cors_origins = tuple(aslist(settings['cors_origins']))\n        cors_max_age = settings['cors_max_age_seconds']\n        cls.cors_max_age = int(cors_max_age) if cors_max_age else None\n\n\ndef includeme(config):\n    settings = config.get_settings()\n\n    # Heartbeat registry.\n    config.registry.heartbeats = {}\n\n    # Public settings registry.\n    config.registry.public_settings = {'batch_max_requests', 'readonly'}\n\n    # Directive to declare arbitrary API capabilities.\n    def add_api_capability(config, identifier, description=\"\", url=\"\", **kw):\n        existing = config.registry.api_capabilities.get(identifier)\n        if existing:\n            error_msg = \"The '%s' API capability was already registered (%s).\"\n            raise ValueError(error_msg % (identifier, existing))\n\n        capability = dict(description=description, url=url, **kw)\n        config.registry.api_capabilities[identifier] = capability\n\n    config.add_directive('add_api_capability', add_api_capability)\n    config.registry.api_capabilities = {}\n\n    # Resource events helpers.\n    config.add_request_method(events.get_resource_events,\n                              name='get_resource_events')\n    config.add_request_method(events.notify_resource_event,\n                              name='notify_resource_event')\n\n    # Setup cornice.\n    config.include(\"cornice\")\n\n    # Per-request transaction.\n    config.include(\"pyramid_tm\")\n\n    # Add CORS settings to the base kinto.core Service class.\n    Service.init_from_settings(settings)\n\n    # Setup components.\n    for step in aslist(settings['initialization_sequence']):\n        step_func = config.maybe_dotted(step)\n        step_func(config)\n\n    # Custom helpers.\n    config.add_request_method(follow_subrequest)\n    config.add_request_method(authentication.prefixed_userid, property=True)\n    config.add_request_method(lambda r: {'id': r.prefixed_userid},\n                              name='get_user_info')\n    config.add_request_method(current_resource_name, reify=True)\n    config.add_request_method(current_service, reify=True)\n    config.commit()\n\n    # Include plugins after init, unlike pyramid includes.\n    includes = aslist(settings['includes'])\n    for app in includes:\n        config.include(app)\n\n    # # Show settings to output.\n    # for key, value in settings.items():\n    #     logger.info('Using %s = %s' % (key, value))\n\n    # Scan views.\n    config.scan(\"kinto.core.views\")\n\n    # Give sign of life.\n    msg = \"%(project_name)s %(project_version)s starting.\"\n    logger.info(msg % settings)\n", "path": "kinto/core/__init__.py"}, {"content": "import platform\nimport codecs\nimport os\nfrom setuptools import setup, find_packages\n\nhere = os.path.abspath(os.path.dirname(__file__))\n\ndef read_file(filename):\n    \"\"\"Open a related file and return its content.\"\"\"\n    with codecs.open(os.path.join(here, filename), encoding='utf-8') as f:\n        content = f.read()\n    return content\n\nREADME = read_file('README.rst')\nCHANGELOG = read_file('CHANGELOG.rst')\nCONTRIBUTORS = read_file('CONTRIBUTORS.rst')\n\ninstalled_with_pypy = platform.python_implementation() == 'PyPy'\n\nREQUIREMENTS = [\n    'colander',\n    'colorama',\n    'cornice >= 1.1',  # Fix cache CORS\n    'jsonschema',\n    'python-dateutil',\n    'pyramid_multiauth >= 0.8',  # User on policy selected event.\n    'pyramid_tm',\n    'redis',  # Default backend\n    'requests',\n    'six',\n    'structlog >= 16.1.0',\n    'enum34',\n    'waitress',\n]\n\nif installed_with_pypy:\n    # We install psycopg2cffi instead of psycopg2 when dealing with pypy\n    # Note: JSONB support landed after psycopg2cffi 2.7.0\n    POSTGRESQL_REQUIRES = [\n        'SQLAlchemy',\n        'psycopg2cffi>2.7.0',\n        'zope.sqlalchemy',\n    ]\nelse:\n    # ujson is not pypy compliant, as it uses the CPython C API\n    REQUIREMENTS.append('ujson >= 1.35')\n    POSTGRESQL_REQUIRES = [\n        'SQLAlchemy',\n        'psycopg2>2.5',\n        'zope.sqlalchemy',\n    ]\n\nDEPENDENCY_LINKS = [\n]\n\nMONITORING_REQUIRES = [\n    'raven',\n    'statsd',\n    'newrelic',\n    'werkzeug',\n]\n\nENTRY_POINTS = {\n    'paste.app_factory': [\n        'main = kinto:main',\n    ],\n    'console_scripts': [\n        'kinto = kinto.__main__:main'\n    ],\n}\n\n\nsetup(name='kinto',\n      version='3.1.1.dev0',\n      description='Kinto Web Service - Store, Sync, Share, and Self-Host.',\n      long_description=README + \"\\n\\n\" + CHANGELOG + \"\\n\\n\" + CONTRIBUTORS,\n      license='Apache License (2.0)',\n      classifiers=[\n          \"Programming Language :: Python\",\n          \"Programming Language :: Python :: 2\",\n          \"Programming Language :: Python :: 2.7\",\n          \"Programming Language :: Python :: 3\",\n          \"Programming Language :: Python :: 3.4\",\n          \"Programming Language :: Python :: 3.5\",\n          \"Programming Language :: Python :: Implementation :: CPython\",\n          \"Programming Language :: Python :: Implementation :: PyPy\",\n          \"Topic :: Internet :: WWW/HTTP\",\n          \"Topic :: Internet :: WWW/HTTP :: WSGI :: Application\",\n          \"License :: OSI Approved :: Apache Software License\"\n      ],\n      keywords=\"web sync json storage services\",\n      author='Mozilla Services',\n      author_email='storage-team@mozilla.com',\n      url='https://github.com/Kinto/kinto',\n      packages=find_packages(),\n      package_data={'': ['*.rst', '*.py']},\n      include_package_data=True,\n      zip_safe=False,\n      install_requires=REQUIREMENTS,\n      extras_require={\n          'postgresql': POSTGRESQL_REQUIRES,\n          'monitoring': MONITORING_REQUIRES,\n          \":python_version=='2.7'\": [\"functools32\"],\n      },\n      test_suite=\"kinto.tests\",\n      dependency_links=DEPENDENCY_LINKS,\n      entry_points=ENTRY_POINTS)\n", "path": "setup.py"}, {"content": "from pyramid.security import NO_PERMISSION_REQUIRED\n\nfrom kinto.core import Service\n\nheartbeat = Service(name=\"heartbeat\", path='/__heartbeat__',\n                    description=\"Server health\")\n\n\n@heartbeat.get(permission=NO_PERMISSION_REQUIRED)\ndef get_heartbeat(request):\n    \"\"\"Return information about server health.\"\"\"\n    status = {}\n\n    heartbeats = request.registry.heartbeats\n    for name, callable in heartbeats.items():\n        status[name] = callable(request)\n\n    has_error = not all([v or v is None for v in status.values()])\n    if has_error:\n        request.response.status = 503\n\n    return status\n\n\nlbheartbeat = Service(name=\"lbheartbeat\", path='/__lbheartbeat__',\n                      description=\"Web head health\")\n\n\n@lbheartbeat.get(permission=NO_PERMISSION_REQUIRED)\ndef get_lbheartbeat(request):\n    \"\"\"Return successful healthy response.\n\n    If the load-balancer tries to access this URL and fails, this means the\n    Web head is not operational and should be dropped.\n    \"\"\"\n    status = {}\n    return status\n", "path": "kinto/core/views/heartbeat.py"}], "after_files": [{"content": "\"\"\"Main entry point\n\"\"\"\nimport pkg_resources\n\nfrom cornice import Service as CorniceService\nfrom pyramid.settings import aslist\n\nfrom kinto.core import authentication\nfrom kinto.core import errors\nfrom kinto.core import events\nfrom kinto.core.initialization import (  # NOQA\n    initialize, install_middlewares,\n    load_default_settings)\nfrom kinto.core.utils import (\n    follow_subrequest, current_service, current_resource_name)\nfrom kinto.core.logs import logger\n\n\n# Module version, as defined in PEP-0396.\n__version__ = pkg_resources.get_distribution('kinto').version  # FIXME?\n\n\nDEFAULT_SETTINGS = {\n    'backoff': None,\n    'batch_max_requests': 25,\n    'cache_backend': '',\n    'cache_url': '',\n    'cache_pool_size': 25,\n    'cache_prefix': '',\n    'cors_origins': '*',\n    'cors_max_age_seconds': 3600,\n    'eos': None,\n    'eos_message': None,\n    'eos_url': None,\n    'error_info_link': 'https://github.com/Kinto/kinto/issues/',\n    'http_host': None,\n    'http_scheme': None,\n    'id_generator': 'kinto.core.storage.generators.UUID4',\n    'includes': '',\n    'initialization_sequence': (\n        'kinto.core.initialization.setup_request_bound_data',\n        'kinto.core.initialization.setup_json_serializer',\n        'kinto.core.initialization.setup_logging',\n        'kinto.core.initialization.setup_storage',\n        'kinto.core.initialization.setup_permission',\n        'kinto.core.initialization.setup_cache',\n        'kinto.core.initialization.setup_requests_scheme',\n        'kinto.core.initialization.setup_version_redirection',\n        'kinto.core.initialization.setup_deprecation',\n        'kinto.core.initialization.setup_authentication',\n        'kinto.core.initialization.setup_backoff',\n        'kinto.core.initialization.setup_statsd',\n        'kinto.core.initialization.setup_listeners',\n        'kinto.core.events.setup_transaction_hook',\n    ),\n    'event_listeners': '',\n    'heartbeat_timeout_seconds': 10,\n    'logging_renderer': 'kinto.core.logs.ClassicLogRenderer',\n    'newrelic_config': None,\n    'newrelic_env': 'dev',\n    'paginate_by': None,\n    'permission_backend': '',\n    'permission_url': '',\n    'permission_pool_size': 25,\n    'profiler_dir': '/tmp',\n    'profiler_enabled': False,\n    'project_docs': '',\n    'project_name': '',\n    'project_version': '',\n    'readonly': False,\n    'retry_after_seconds': 30,\n    'statsd_prefix': 'kinto.core',\n    'statsd_url': None,\n    'storage_backend': '',\n    'storage_url': '',\n    'storage_max_fetch_size': 10000,\n    'storage_pool_size': 25,\n    'tm.annotate_user': False,  # Do annotate transactions with the user-id.\n    'transaction_per_request': True,\n    'userid_hmac_secret': '',\n    'version_prefix_redirect_enabled': True,\n    'trailing_slash_redirect_enabled': True,\n    'multiauth.groupfinder': 'kinto.core.authorization.groupfinder',\n    'multiauth.policies': 'basicauth',\n    'multiauth.policy.basicauth.use': ('kinto.core.authentication.'\n                                       'BasicAuthAuthenticationPolicy'),\n    'multiauth.authorization_policy': ('kinto.core.authorization.'\n                                       'AuthorizationPolicy')\n}\n\n\nclass Service(CorniceService):\n    \"\"\"Subclass of the default cornice service.\n\n    This is useful in order to attach specific behaviours without monkey\n    patching the default cornice service (which would impact other uses of it)\n    \"\"\"\n    default_cors_headers = ('Backoff', 'Retry-After', 'Alert',\n                            'Content-Length')\n\n    def error_handler(self, error):\n        return errors.json_error_handler(error)\n\n    @classmethod\n    def init_from_settings(cls, settings):\n        cls.cors_origins = tuple(aslist(settings['cors_origins']))\n        cors_max_age = settings['cors_max_age_seconds']\n        cls.cors_max_age = int(cors_max_age) if cors_max_age else None\n\n\ndef includeme(config):\n    settings = config.get_settings()\n\n    # Heartbeat registry.\n    config.registry.heartbeats = {}\n\n    # Public settings registry.\n    config.registry.public_settings = {'batch_max_requests', 'readonly'}\n\n    # Directive to declare arbitrary API capabilities.\n    def add_api_capability(config, identifier, description=\"\", url=\"\", **kw):\n        existing = config.registry.api_capabilities.get(identifier)\n        if existing:\n            error_msg = \"The '%s' API capability was already registered (%s).\"\n            raise ValueError(error_msg % (identifier, existing))\n\n        capability = dict(description=description, url=url, **kw)\n        config.registry.api_capabilities[identifier] = capability\n\n    config.add_directive('add_api_capability', add_api_capability)\n    config.registry.api_capabilities = {}\n\n    # Resource events helpers.\n    config.add_request_method(events.get_resource_events,\n                              name='get_resource_events')\n    config.add_request_method(events.notify_resource_event,\n                              name='notify_resource_event')\n\n    # Setup cornice.\n    config.include(\"cornice\")\n\n    # Per-request transaction.\n    config.include(\"pyramid_tm\")\n\n    # Add CORS settings to the base kinto.core Service class.\n    Service.init_from_settings(settings)\n\n    # Setup components.\n    for step in aslist(settings['initialization_sequence']):\n        step_func = config.maybe_dotted(step)\n        step_func(config)\n\n    # Custom helpers.\n    config.add_request_method(follow_subrequest)\n    config.add_request_method(authentication.prefixed_userid, property=True)\n    config.add_request_method(lambda r: {'id': r.prefixed_userid},\n                              name='get_user_info')\n    config.add_request_method(current_resource_name, reify=True)\n    config.add_request_method(current_service, reify=True)\n    config.commit()\n\n    # Include plugins after init, unlike pyramid includes.\n    includes = aslist(settings['includes'])\n    for app in includes:\n        config.include(app)\n\n    # # Show settings to output.\n    # for key, value in settings.items():\n    #     logger.info('Using %s = %s' % (key, value))\n\n    # Scan views.\n    config.scan(\"kinto.core.views\")\n\n    # Give sign of life.\n    msg = \"%(project_name)s %(project_version)s starting.\"\n    logger.info(msg % settings)\n", "path": "kinto/core/__init__.py"}, {"content": "import platform\nimport codecs\nimport os\nfrom setuptools import setup, find_packages\n\nhere = os.path.abspath(os.path.dirname(__file__))\n\ndef read_file(filename):\n    \"\"\"Open a related file and return its content.\"\"\"\n    with codecs.open(os.path.join(here, filename), encoding='utf-8') as f:\n        content = f.read()\n    return content\n\nREADME = read_file('README.rst')\nCHANGELOG = read_file('CHANGELOG.rst')\nCONTRIBUTORS = read_file('CONTRIBUTORS.rst')\n\ninstalled_with_pypy = platform.python_implementation() == 'PyPy'\n\nREQUIREMENTS = [\n    'colander',\n    'colorama',\n    'cornice >= 1.1',  # Fix cache CORS\n    'jsonschema',\n    'python-dateutil',\n    'pyramid_multiauth >= 0.8',  # User on policy selected event.\n    'pyramid_tm',\n    'redis',  # Default backend\n    'requests',\n    'six',\n    'structlog >= 16.1.0',\n    'enum34',\n    'waitress',\n]\n\nif installed_with_pypy:\n    # We install psycopg2cffi instead of psycopg2 when dealing with pypy\n    # Note: JSONB support landed after psycopg2cffi 2.7.0\n    POSTGRESQL_REQUIRES = [\n        'SQLAlchemy',\n        'psycopg2cffi>2.7.0',\n        'zope.sqlalchemy',\n    ]\nelse:\n    # ujson is not pypy compliant, as it uses the CPython C API\n    REQUIREMENTS.append('ujson >= 1.35')\n    POSTGRESQL_REQUIRES = [\n        'SQLAlchemy',\n        'psycopg2>2.5',\n        'zope.sqlalchemy',\n    ]\n\nDEPENDENCY_LINKS = [\n]\n\nMONITORING_REQUIRES = [\n    'raven',\n    'statsd',\n    'newrelic',\n    'werkzeug',\n]\n\nENTRY_POINTS = {\n    'paste.app_factory': [\n        'main = kinto:main',\n    ],\n    'console_scripts': [\n        'kinto = kinto.__main__:main'\n    ],\n}\n\n\nsetup(name='kinto',\n      version='3.1.1.dev0',\n      description='Kinto Web Service - Store, Sync, Share, and Self-Host.',\n      long_description=README + \"\\n\\n\" + CHANGELOG + \"\\n\\n\" + CONTRIBUTORS,\n      license='Apache License (2.0)',\n      classifiers=[\n          \"Programming Language :: Python\",\n          \"Programming Language :: Python :: 2\",\n          \"Programming Language :: Python :: 2.7\",\n          \"Programming Language :: Python :: 3\",\n          \"Programming Language :: Python :: 3.4\",\n          \"Programming Language :: Python :: 3.5\",\n          \"Programming Language :: Python :: Implementation :: CPython\",\n          \"Programming Language :: Python :: Implementation :: PyPy\",\n          \"Topic :: Internet :: WWW/HTTP\",\n          \"Topic :: Internet :: WWW/HTTP :: WSGI :: Application\",\n          \"License :: OSI Approved :: Apache Software License\"\n      ],\n      keywords=\"web sync json storage services\",\n      author='Mozilla Services',\n      author_email='storage-team@mozilla.com',\n      url='https://github.com/Kinto/kinto',\n      packages=find_packages(),\n      package_data={'': ['*.rst', '*.py']},\n      include_package_data=True,\n      zip_safe=False,\n      install_requires=REQUIREMENTS,\n      extras_require={\n          'postgresql': POSTGRESQL_REQUIRES,\n          'monitoring': MONITORING_REQUIRES,\n          \":python_version=='2.7'\": [\"functools32\", \"futures\"],\n      },\n      test_suite=\"kinto.tests\",\n      dependency_links=DEPENDENCY_LINKS,\n      entry_points=ENTRY_POINTS)\n", "path": "setup.py"}, {"content": "from concurrent.futures import ThreadPoolExecutor, wait\nfrom pyramid.security import NO_PERMISSION_REQUIRED\n\nfrom kinto import logger\nfrom kinto.core import Service\n\n\nheartbeat = Service(name=\"heartbeat\", path='/__heartbeat__',\n                    description=\"Server health\")\n\n\n@heartbeat.get(permission=NO_PERMISSION_REQUIRED)\ndef get_heartbeat(request):\n    \"\"\"Return information about server health.\"\"\"\n    status = {}\n\n    def heartbeat_check(name, func):\n        status[name] = False\n        status[name] = func(request)\n\n    # Start executing heartbeats concurrently.\n    heartbeats = request.registry.heartbeats\n    pool = ThreadPoolExecutor(max_workers=max(1, len(heartbeats.keys())))\n    futures = []\n    for name, func in heartbeats.items():\n        future = pool.submit(heartbeat_check, name, func)\n        future.__heartbeat_name = name  # For logging purposes.\n        futures.append(future)\n\n    # Wait for the results, with timeout.\n    seconds = float(request.registry.settings['heartbeat_timeout_seconds'])\n    done, not_done = wait(futures, timeout=seconds)\n\n    # A heartbeat is supposed to return True or False, and never raise.\n    # Just in case, go though results to spot any potential exception.\n    for future in done:\n        exc = future.exception()\n        if exc is not None:\n            logger.error(\"%r heartbeat failed.\" % future.__heartbeat_name)\n            logger.error(exc)\n\n    # Log timed-out heartbeats.\n    for future in not_done:\n        name = future.__heartbeat_name\n        error_msg = \"%r heartbeat has exceeded timeout of %s seconds.\"\n        logger.error(error_msg % (name, seconds))\n\n    # If any has failed, return a 503 error response.\n    has_error = not all([v or v is None for v in status.values()])\n    if has_error:\n        request.response.status = 503\n\n    return status\n\n\nlbheartbeat = Service(name=\"lbheartbeat\", path='/__lbheartbeat__',\n                      description=\"Web head health\")\n\n\n@lbheartbeat.get(permission=NO_PERMISSION_REQUIRED)\ndef get_lbheartbeat(request):\n    \"\"\"Return successful healthy response.\n\n    If the load-balancer tries to access this URL and fails, this means the\n    Web head is not operational and should be dropped.\n    \"\"\"\n    status = {}\n    return status\n", "path": "kinto/core/views/heartbeat.py"}]}