Skip to content

Commit 696959c

Browse files
committed
Add TODO.md
1 parent 7f27471 commit 696959c

File tree

1 file changed

+272
-0
lines changed

1 file changed

+272
-0
lines changed

TODO.md

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
## Documentation
2+
3+
- A function with an extensions has a shutdown timeout of 2s.
4+
- 2,000 ms – A function with one or more registered external extensions
5+
6+
#### CloudWatch Metrics
7+
8+
When using Extensions, your function's CloudWatch `Duration` metrics will be the sum of your response time combined with your extension's execution time. For example, if your request takes `200ms` to respond but your need to process a background task which takes `1000ms` your duration will be `1200ms` total. For more details see the "Performance impact and extension overhead" section of the [Lambda Extensions API
9+
](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html)
10+
11+
Thankfully, when using Lambda Extensions, CloudWatch will create a `PostRuntimeExtensionsDuration` metric that you can use to isolate your true response times `Duration` [using some metric math](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html). Here is an example
12+
13+
#### Logging
14+
15+
Default :fatal.
16+
17+
```yaml
18+
Environment:
19+
Variables:
20+
LAMBDA_PUNCH_LOG_LEVEL: debug
21+
```
22+
23+
## Development
24+
25+
```ruby
26+
27+
# Queuing Works
28+
class Queue
29+
JOBS = []
30+
def self.push(block)
31+
JOBS << block
32+
end
33+
end
34+
module LambdaPunch
35+
def push(&block)
36+
Queue.push(block)
37+
end
38+
extend self
39+
end
40+
LambdaPunch.push do
41+
sleep(1)
42+
end
43+
44+
# Seconds to Milliseconds
45+
(1000.0 * 0.1).to_i # => 100
46+
(1000.0 * 0.01).to_i # => 10
47+
48+
# Milliseconds to Seconds
49+
100 / 1000.0 # => 0.1
50+
10 / 1000.0 # => 0.01
51+
52+
>> Timeout.timeout(0.01) { sleep(0.009) }
53+
>> Timeout.timeout(0.01) { sleep(0.011) }
54+
Timeout::Error (execution expired)
55+
56+
57+
# Do concurrent ruby timeouts do anything when not needed? No!
58+
require 'concurrent'
59+
require 'concurrent/edge/cancellation'
60+
t = Concurrent::Cancellation.timeout(10)
61+
Concurrent.global_io_executor.post(t) do |timeout|
62+
puts 'here'
63+
end
64+
65+
66+
# Final working solution I like.
67+
require 'rb-inotify'
68+
require 'concurrent'
69+
require 'concurrent/edge/cancellation'
70+
@file = "./lambdapunch-handled"
71+
File.open(@file, 'w') { |f| f.write('') }
72+
def noop ; true ; end
73+
def noopn(n) ; sleep(n) ; end
74+
@request_id = nil
75+
@notifier = INotify::Notifier.new
76+
@notifier.watch(@file, :modify, :oneshot) { File.read(@file) }
77+
def p1
78+
@c1, @o1 = Concurrent::Cancellation.new
79+
@p1 = Concurrent::Promises.future do
80+
@notifier.process
81+
puts 'notified'
82+
File.read(@file)
83+
end
84+
end
85+
def p2
86+
@c2 = Concurrent::Cancellation.timeout(60)
87+
@p2 = Concurrent::Promises.future do
88+
noop until @c1.canceled? || @c2.canceled?
89+
if @c2.canceled?
90+
puts 'timeout'
91+
@c1.origin.resolve
92+
:timeout
93+
else
94+
puts 'notifier_resolved'
95+
:notifier_resolved
96+
end
97+
end
98+
end
99+
@p3 = Concurrent::Promises.any_resolved_future(p2, p1)
100+
File.open(@file,'w') { |f| f.write('123') }
101+
@p3.wait.value
102+
@notifier.close
103+
104+
105+
106+
107+
108+
p1 = Concurrent::Promises.future do
109+
do_stuff until c.canceled?
110+
111+
end
112+
# => #
113+
114+
c.origin.resolve
115+
# => #
116+
async_task.value!
117+
118+
119+
120+
121+
122+
123+
124+
125+
@i = 1
126+
def do_stuff ; @i += 1 ; end
127+
c, o = Concurrent::Cancellation.new
128+
Concurrent::Promises.future(c) do |c|
129+
# Do work repeatedly until it is cancelled
130+
do_stuff until c.canceled?
131+
:stopped_gracefully
132+
end
133+
o.resolve
134+
135+
require 'concurrent'
136+
require 'concurrent/edge/cancellation'
137+
@i = 1
138+
def do_stuff ; @i += 1 ; end
139+
# t = Concurrent::Cancellation.new Concurrent::Promises.schedule(0.02)
140+
t = Concurrent::Cancellation.timeout 59.99802703818213
141+
p = Concurrent.global_io_executor.post(t) do |t|
142+
do_stuff until t.canceled?
143+
puts('here')
144+
:done
145+
end
146+
t.origin.resolve
147+
t.origin.resolved?
148+
t.origin.wait
149+
puts 'here'
150+
151+
c, o = Concurrent::Cancellation.new
152+
p = Concurrent::Promises.future(c) do |c|
153+
true until c.canceled?
154+
end
155+
156+
157+
158+
159+
p1 = Concurrent::Promises.future(3) do |n|
160+
sleep(n)
161+
puts "notifier#{n}"
162+
n
163+
end
164+
p2 = Concurrent::Promises.future(5) do |n|
165+
sleep(n)
166+
puts "notifier#{n}"
167+
n
168+
end
169+
Concurrent::Promises.any_resolved_future(p1,p2).wait.value
170+
171+
172+
173+
174+
require 'concurrent'
175+
require 'concurrent/edge/cancellation'
176+
@i = 1
177+
def do_stuff ; @i += 1 ; end
178+
p1 = Concurrent::Promises.future(3) do |n|
179+
sleep(n)
180+
puts "notifier#{n}"
181+
n
182+
end
183+
p2 = Concurrent::Promises.future(5) do |n|
184+
sleep(n)
185+
puts "notifier#{n}"
186+
n
187+
end
188+
Concurrent::Promises.any_resolved_future(p1,p2).wait.value
189+
190+
c = Concurrent::Cancellation.timeout(12.882)
191+
p2 = Concurrent::Promises.future(c) do |c|
192+
do_stuff until c.canceled?
193+
puts 'timeout'
194+
:request_id_payload
195+
end
196+
Concurrent::Promises.any_resolved_future(p1,p2).wait
197+
198+
199+
@i = 1
200+
@rid = 'aaa-bbb-ccc'
201+
def do_stuff ; @i += 1 ; if @i == 588928 ; @invoked = true ; end ; end
202+
t = Concurrent::Cancellation.timeout 5
203+
p = Concurrent::Promises.future do
204+
do_stuff until @invoked || t.canceled?
205+
@rid
206+
end
207+
p.wait
208+
209+
@invoked = false
210+
211+
!t.canceled?
212+
213+
p = Concurrent::Promises.future(t) { |t| }
214+
while
215+
puts 't'
216+
end
217+
t.cancel
218+
puts 'here'
219+
220+
p.set('test')
221+
222+
p.fulfill('test')
223+
t.origin.wait
224+
225+
226+
t.origin.wait
227+
puts 'here'
228+
229+
230+
231+
232+
233+
234+
Time.at(1624399969622/1000.0)
235+
=> 2021-06-22 18:12:49 2608857/4194304 -0400
236+
237+
(Time.at(1624399969622/1000.0).to_f * 1000.0).to_i
238+
=> 1624399969622
239+
240+
>> Time.at(1624399969622/1000.0) < Time.at(1624399969623/1000.0)
241+
=> true
242+
>> Time.at(1624399969622/1000.0) < Time.at(1624399969621/1000.0)
243+
=> false
244+
```
245+
246+
## Benchmarks
247+
248+
ab -n 100 -c 1 ...
249+
250+
Time taken for tests: 12.814 seconds
251+
252+
50% 124
253+
66% 127
254+
75% 128
255+
80% 129
256+
90% 143
257+
95% 175
258+
98% 202
259+
99% 212
260+
100% 212 (longest request)
261+
262+
Time taken for tests: 12.998 seconds
263+
264+
50% 125
265+
66% 130
266+
75% 133
267+
80% 135
268+
90% 146
269+
95% 176
270+
98% 200
271+
99% 206
272+
100% 206 (longest request)

0 commit comments

Comments
 (0)