This repository has been archived by the owner on Dec 25, 2023. It is now read-only.
/
fibo.py
105 lines (83 loc) · 2.65 KB
/
fibo.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
#
# Copyright 2008 The ndb Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""A web app to test multi-threading."""
import logging
import sys
import threading
import time
from google.appengine.api import memcache
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
import ndb
@ndb.tasklet
def fibonacci(n):
"""A recursive Fibonacci to exercise task switching."""
if n <= 1:
raise ndb.Return(n)
a, b = yield fibonacci(n - 1), fibonacci(n - 2)
raise ndb.Return(a + b)
class FibonacciMemo(ndb.Model):
arg = ndb.IntegerProperty()
value = ndb.IntegerProperty()
@ndb.tasklet
def memoizing_fibonacci(n):
"""A memoizing recursive Fibonacci to exercise RPCs."""
if n <= 1:
raise ndb.Return(n)
key = ndb.Key(FibonacciMemo, str(n))
memo = yield key.get_async(ndb_should_cache=False)
if memo is not None:
assert memo.arg == n
logging.info('memo hit: %d -> %d', n, memo.value)
raise ndb.Return(memo.value)
logging.info('memo fail: %d', n)
a = yield memoizing_fibonacci(n - 1)
b = yield memoizing_fibonacci(n - 2)
ans = a + b
memo = FibonacciMemo(key=key, arg=n, value=ans)
logging.info('memo write: %d -> %d', n, memo.value)
yield memo.put_async(ndb_should_cache=False)
raise ndb.Return(ans)
TRUE_VALUES = frozenset(['1', 'on', 't', 'true', 'y', 'yes'])
class FiboHandler(webapp.RequestHandler):
@ndb.toplevel
def get(self):
num = 10
try:
num = int(self.request.get('num'))
except Exception:
pass
if self.request.get('reset') in TRUE_VALUES:
logging.info('flush')
yield ndb.delete_multi_async(x.key for x in FibonacciMemo.query())
t0 = time.time()
if self.request.get('memo') in TRUE_VALUES:
memo_type = 'memoizing '
ans = yield memoizing_fibonacci(num)
else:
memo_type = ''
ans = yield fibonacci(num)
t1 = time.time()
self.response.out.write('%sfibonacci(%d) == %d # computed in %.3f\n' %
(memo_type, num, ans, t1 - t0))
urls = [
('/fibo', FiboHandler),
]
app = webapp.WSGIApplication(urls)
def main():
util.run_wsgi_app(app)
if __name__ == '__main__':
main()