polyphony 0.43.3 → 0.43.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/docs/getting-started/overview.md +2 -2
- data/examples/performance/mem-usage.rb +34 -28
- data/ext/polyphony/libev_agent.c +16 -8
- data/lib/polyphony.rb +2 -10
- data/lib/polyphony/core/global_api.rb +1 -1
- data/lib/polyphony/extensions/core.rb +25 -0
- data/lib/polyphony/extensions/io.rb +1 -1
- data/lib/polyphony/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9481b252526ebc3f8e0f5a0121eebb68492bc0c1502cfed447da7b0648e6095b
|
4
|
+
data.tar.gz: dfd2d5d0415833f14f9ebe2cc6336e87d0951ce86f07ebcdec0ad892f71fb74c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 652633b1fc27623edb2e87b5657322ba4826ec176e8eb5131a43249e08340f793ba426743be343bfe0fce02fc60b73cb790afef816a4153585d68bdfeaa9c55d
|
7
|
+
data.tar.gz: 946abb7526324cae5f1d6b62e25c8410129b07ca75c82a6b7285d6269ed1911e161a6030a394ef29ba238a80da6f96787dd94fdbd5c05bd2a643379252ce80d0
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -279,7 +279,7 @@ def chat_user_handler(user_name, connection)
|
|
279
279
|
while command = connection.gets
|
280
280
|
case command
|
281
281
|
when /^connect (.+)/
|
282
|
-
room&.send [:
|
282
|
+
room&.send [:subscribe, message_subscriber]
|
283
283
|
room = CHAT_ROOMS[$1]
|
284
284
|
when "disconnect"
|
285
285
|
room&.send [:unsubscribe, message_subscriber]
|
@@ -483,4 +483,4 @@ reach version 1.0. Here are some of the exciting directions we're working on.
|
|
483
483
|
- Support for more core and stdlib APIs
|
484
484
|
- More adapters for gems with C-extensions, such as `mysql`, `sqlite3` etc
|
485
485
|
- Use `io_uring` agent as alternative to the libev agent
|
486
|
-
- More concurrency constructs for building highly concurrent applications
|
486
|
+
- More concurrency constructs for building highly concurrent applications
|
@@ -4,47 +4,53 @@ def mem_usage
|
|
4
4
|
`ps -o rss #{$$}`.split.last.to_i
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def calculate_memory_cost(name, count, &block)
|
8
|
+
GC.enable
|
9
|
+
ObjectSpace.garbage_collect
|
10
|
+
sleep 0.5
|
8
11
|
GC.disable
|
9
12
|
rss0 = mem_usage
|
10
|
-
|
13
|
+
count0 = ObjectSpace.count_objects[:TOTAL] - ObjectSpace.count_objects[:FREE]
|
14
|
+
a = []
|
15
|
+
count.times { a << block.call }
|
11
16
|
rss1 = mem_usage
|
12
|
-
|
17
|
+
count1 = ObjectSpace.count_objects[:TOTAL] - ObjectSpace.count_objects[:FREE]
|
18
|
+
p [count0, count1]
|
19
|
+
# sleep 0.5
|
13
20
|
cost = (rss1 - rss0).to_f / count
|
21
|
+
count_delta = (count1 - count0) / count
|
14
22
|
|
15
|
-
puts "
|
23
|
+
puts "#{name} rss cost: #{cost}KB object count: #{count_delta}"
|
16
24
|
end
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
def calculate_thread_memory_cost(count)
|
21
|
-
GC.disable
|
22
|
-
rss0 = mem_usage
|
23
|
-
count.times { Thread.new { sleep 1 } }
|
24
|
-
sleep 0.5
|
25
|
-
rss1 = mem_usage
|
26
|
-
sleep 0.5
|
27
|
-
GC.start
|
28
|
-
cost = (rss1 - rss0).to_f / count
|
26
|
+
f = Fiber.new { |f| f.transfer }
|
27
|
+
f.transfer Fiber.current
|
29
28
|
|
30
|
-
|
29
|
+
calculate_memory_cost('fiber', 10000) do
|
30
|
+
f = Fiber.new { |f| f.transfer :foo }
|
31
|
+
f.transfer Fiber.current
|
32
|
+
f
|
31
33
|
end
|
32
34
|
|
33
|
-
|
35
|
+
t = Thread.new { sleep 1}
|
36
|
+
t.kill
|
37
|
+
t.join
|
38
|
+
|
39
|
+
calculate_memory_cost('thread', 500) do
|
40
|
+
t = Thread.new { sleep 1 }
|
41
|
+
sleep 0.001
|
42
|
+
t
|
43
|
+
end
|
44
|
+
(Thread.list - [Thread.current]).each(&:kill).each(&:join)
|
34
45
|
|
35
46
|
require 'bundler/setup'
|
36
47
|
require 'polyphony'
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
rss0 = mem_usage
|
41
|
-
count.times { spin { :foo } }
|
42
|
-
snooze
|
43
|
-
rss1 = mem_usage
|
44
|
-
GC.start
|
45
|
-
cost = (rss1 - rss0).to_f / count
|
49
|
+
f = spin { sleep 0.1 }
|
50
|
+
f.await
|
46
51
|
|
47
|
-
|
52
|
+
calculate_memory_cost('polyphony fiber', 10000) do
|
53
|
+
f = spin { :foo }
|
54
|
+
f.await
|
55
|
+
f
|
48
56
|
end
|
49
|
-
|
50
|
-
calculate_extended_fiber_memory_cost(10000)
|
data/ext/polyphony/libev_agent.c
CHANGED
@@ -281,7 +281,8 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
|
|
281
281
|
struct LibevAgent_t *agent;
|
282
282
|
struct libev_io watcher;
|
283
283
|
rb_io_t *fptr;
|
284
|
-
long
|
284
|
+
long dynamic_len = length == Qnil;
|
285
|
+
long len = dynamic_len ? 4096 : NUM2INT(length);
|
285
286
|
int shrinkable = io_setstrbuf(&str, len);
|
286
287
|
char *buf = RSTRING_PTR(str);
|
287
288
|
long total = 0;
|
@@ -298,8 +299,8 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
|
|
298
299
|
|
299
300
|
OBJ_TAINT(str);
|
300
301
|
|
301
|
-
while (
|
302
|
-
ssize_t n = read(fptr->fd, buf, len);
|
302
|
+
while (1) {
|
303
|
+
ssize_t n = read(fptr->fd, buf, len - total);
|
303
304
|
if (n < 0) {
|
304
305
|
int e = errno;
|
305
306
|
if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
|
@@ -312,14 +313,21 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
|
|
312
313
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
313
314
|
|
314
315
|
if (n == 0) break; // EOF
|
315
|
-
|
316
316
|
total = total + n;
|
317
|
-
|
318
|
-
|
319
|
-
if (
|
317
|
+
if (!read_to_eof) break;
|
318
|
+
|
319
|
+
if (total == len) {
|
320
|
+
if (!dynamic_len) break;
|
321
|
+
|
322
|
+
rb_str_resize(str, total);
|
323
|
+
rb_str_modify_expand(str, len);
|
324
|
+
buf = RSTRING_PTR(str) + total;
|
325
|
+
shrinkable = 0;
|
326
|
+
len += len;
|
327
|
+
}
|
328
|
+
else buf += n;
|
320
329
|
}
|
321
330
|
}
|
322
|
-
|
323
331
|
if (total == 0) return Qnil;
|
324
332
|
|
325
333
|
io_set_read_length(str, total, shrinkable);
|
data/lib/polyphony.rb
CHANGED
@@ -100,17 +100,9 @@ module Polyphony
|
|
100
100
|
Polyphony::Process.watch(cmd, &block)
|
101
101
|
end
|
102
102
|
|
103
|
-
def emit_signal_exception(exception, fiber = Thread.main.main_fiber)
|
104
|
-
Thread.current.break_out_of_ev_loop(fiber, exception)
|
105
|
-
end
|
106
|
-
|
107
|
-
def install_terminating_signal_handler(signal, exception_class)
|
108
|
-
trap(signal) { emit_signal_exception(exception_class.new) }
|
109
|
-
end
|
110
|
-
|
111
103
|
def install_terminating_signal_handlers
|
112
|
-
|
113
|
-
|
104
|
+
trap('SIGTERM', SystemExit)
|
105
|
+
trap('SIGINT', Interrupt)
|
114
106
|
end
|
115
107
|
|
116
108
|
def terminate_threads
|
@@ -126,6 +126,31 @@ module ::Kernel
|
|
126
126
|
break
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
alias_method :orig_trap, :trap
|
131
|
+
def trap(sig, command = nil, &block)
|
132
|
+
return orig_trap(sig, command) if command.is_a? String
|
133
|
+
|
134
|
+
block = command if command.respond_to?(:call) && !block
|
135
|
+
exception = command.is_a?(Class) && command.new
|
136
|
+
|
137
|
+
# The signal trap can be invoked at any time, including while the system
|
138
|
+
# agent is blocking while polling for events. In order to deal with this
|
139
|
+
# correctly, we spin a fiber that will run the signal handler code, then
|
140
|
+
# call break_out_of_ev_loop, which will put the fiber at the front of the
|
141
|
+
# run queue, then wake up the system agent.
|
142
|
+
#
|
143
|
+
# If the command argument is an exception class however, it will be raised
|
144
|
+
# directly in the context of the main fiber.
|
145
|
+
orig_trap(sig) do
|
146
|
+
if exception
|
147
|
+
Thread.current.break_out_of_ev_loop(Thread.main.main_fiber, exception)
|
148
|
+
else
|
149
|
+
fiber = spin { snooze; block.call }
|
150
|
+
Thread.current.break_out_of_ev_loop(fiber, nil)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
129
154
|
end
|
130
155
|
|
131
156
|
# Override Timeout to use cancel scope
|
data/lib/polyphony/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.43.
|
4
|
+
version: 0.43.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|