forked from gratipay/gratipay.com
-
Notifications
You must be signed in to change notification settings - Fork 0
/
configure-aspen.py
178 lines (137 loc) · 5.64 KB
/
configure-aspen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
from __future__ import division
import os
import sys
import threading
import time
import traceback
import gittip
import gittip.wireup
from gittip import canonize, configure_payments
from gittip.security import authentication, csrf, x_frame_options
from gittip.utils import cache_static, timer
from aspen import log_dammit
# Wireup Algorithm
# ================
version_file = os.path.join(website.www_root, 'version.txt')
__version__ = open(version_file).read().strip()
website.version = os.environ['__VERSION__'] = __version__
website.renderer_default = "jinja2"
website.renderer_factories['jinja2'].Renderer.global_context = {
'range': range,
'unicode': unicode,
'enumerate': enumerate,
'len': len,
'float': float,
'type': type,
'str': str
}
gittip.wireup.canonical()
website.db = gittip.wireup.db()
gittip.wireup.billing()
gittip.wireup.username_restrictions(website)
gittip.wireup.nanswers()
gittip.wireup.envvars(website)
tell_sentry = gittip.wireup.make_sentry_teller(website)
# The homepage wants expensive queries. Let's periodically select into an
# intermediate table.
UPDATE_HOMEPAGE_EVERY = int(os.environ['UPDATE_HOMEPAGE_EVERY'])
def update_homepage_queries():
from gittip import utils
while 1:
try:
utils.update_global_stats(website)
utils.update_homepage_queries_once(website.db)
website.db.self_check()
except:
exception = sys.exc_info()[0]
tell_sentry(exception)
tb = traceback.format_exc().strip()
log_dammit(tb)
time.sleep(UPDATE_HOMEPAGE_EVERY)
if UPDATE_HOMEPAGE_EVERY > 0:
homepage_updater = threading.Thread(target=update_homepage_queries)
homepage_updater.daemon = True
homepage_updater.start()
else:
from gittip import utils
utils.update_global_stats(website)
# Server Algorithm
# ================
def up_minthreads(website):
# https://github.com/gittip/www.gittip.com/issues/1098
# Discovered the following API by inspecting in pdb and browsing source.
# This requires network_engine.bind to have already been called.
request_queue = website.network_engine.cheroot_server.requests
request_queue.min = website.min_threads
def setup_busy_threads_logging(website):
# https://github.com/gittip/www.gittip.com/issues/1572
log_every = website.log_busy_threads_every
if log_every == 0:
return
pool = website.network_engine.cheroot_server.requests
def log_busy_threads():
time.sleep(0.5) # without this we get a single log message where all threads are busy
while 1:
# Use pool.min and not pool.max because of the semantics of these
# inside of Cheroot. (Max is a hard limit used only when pool.grow
# is called, and it's never called except when the pool starts up,
# when it's called with pool.min.)
nbusy_threads = pool.min - pool.idle
print("sample#aspen.busy_threads={}".format(nbusy_threads))
time.sleep(log_every)
thread = threading.Thread(target=log_busy_threads)
thread.daemon = True
thread.start()
website.server_algorithm.insert_before('start', up_minthreads)
website.server_algorithm.insert_before('start', setup_busy_threads_logging)
# Website Algorithm
# =================
def add_stuff_to_context(request):
request.context['username'] = None
def scab_body_onto_response(response):
# This is a workaround for a Cheroot bug, where the connection is closed
# too early if there is no body:
#
# https://bitbucket.org/cherrypy/cheroot/issue/1/fail-if-passed-zero-bytes
#
# This Cheroot bug is manifesting because of a change in Aspen's behavior
# with the algorithm.py refactor in 0.27+: Aspen no longer sets a body for
# 302s as it used to. This means that all redirects are breaking
# intermittently (sometimes the client seems not to care that the
# connection is closed too early, so I guess there's some timing
# involved?), which is affecting a number of parts of Gittip, notably
# around logging in (#1859).
if not response.body:
response.body = '*sigh*'
algorithm = website.algorithm
algorithm.functions = [ timer.start
, algorithm['parse_environ_into_request']
, algorithm['tack_website_onto_request']
, algorithm['raise_200_for_OPTIONS']
, canonize
, configure_payments
, authentication.inbound
, csrf.inbound
, add_stuff_to_context
, algorithm['dispatch_request_to_filesystem']
, algorithm['apply_typecasters_to_path']
, cache_static.inbound
, algorithm['get_response_for_socket']
, algorithm['get_resource_for_request']
, algorithm['get_response_for_resource']
, tell_sentry
, algorithm['get_response_for_exception']
, gittip.outbound
, authentication.outbound
, csrf.outbound
, cache_static.outbound
, x_frame_options
, algorithm['log_traceback_for_5xx']
, algorithm['delegate_error_to_simplate']
, tell_sentry
, algorithm['log_traceback_for_exception']
, algorithm['log_result_of_request']
, scab_body_onto_response
, timer.end
, tell_sentry
]