iodine 0.2.16 → 0.2.17
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/bin/config.ru +9 -1
- data/bin/http-big +63 -0
- data/exe/iodine +7 -2
- data/ext/iodine/iodine_core.c +30 -11
- data/lib/iodine/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de923f79329ea2c150786d10000b43b6378612e3
|
4
|
+
data.tar.gz: 97749ca95384e2e5b0487c4bfda183690440257c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40b2d878c483d077421eab48b4be2b02f6c3bb1ebf32cd43c9fc6007fdae110828df6b6d02867d54bf6ae524e3762dd8d9f95277712038a64e1727f00e3a1153
|
7
|
+
data.tar.gz: 289d7f82bd5f2a67621ada01dfc56143ba62c5dbeafcd0b4c5a544a9ba7c992b2c4dff5322b7b0fe21e656f3b9913716d8b523d0c708325028c54fc2a2cfa0bf
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,12 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
8
8
|
|
9
9
|
***
|
10
10
|
|
11
|
+
#### Change log v.0.2.17
|
12
|
+
|
13
|
+
**Performance**: Enhanced Performance for single threaded / blocking applications by adding a dedicated IO thread. This is related to issue #14.
|
14
|
+
|
15
|
+
***
|
16
|
+
|
11
17
|
#### Change log v.0.2.16
|
12
18
|
|
13
19
|
**Update**: iodine can now run as a basic HTTP static file server without a Ruby application (no `config.ru`) when the `-www` option is used from the command line.
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ Iodine is a C extension for Ruby, developed for Ruby MRI 2.2.2 and up... it shou
|
|
24
24
|
|
25
25
|
## Iodine::Rack - an HTTP and Websockets server
|
26
26
|
|
27
|
-
Iodine includes a light and fast HTTP and Websocket server written in C that was written according to the [Rack interface specifications](http://www.rubydoc.info/github/rack/rack/master/file/SPEC) and the Websocket draft extension.
|
27
|
+
Iodine includes a light and fast HTTP and Websocket server written in C that was written according to the [Rack interface specifications](http://www.rubydoc.info/github/rack/rack/master/file/SPEC) and the [Websocket draft extension](./SPEC-Websocket-Draft.md).
|
28
28
|
|
29
29
|
### Running the web server
|
30
30
|
|
data/bin/config.ru
CHANGED
@@ -8,7 +8,7 @@ require 'rack/lint'
|
|
8
8
|
# This value (app) sets which of the different applications will run.
|
9
9
|
#
|
10
10
|
# Valid values are "hello", "slow" (debugs env values), "simple"
|
11
|
-
app = '
|
11
|
+
app = 'big'
|
12
12
|
# This is a simple Hello World Rack application, for benchmarking.
|
13
13
|
HELLO_RESPONSE = [200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
14
14
|
'Content-Length'.freeze => '16'.freeze }.freeze,
|
@@ -48,12 +48,20 @@ simple = proc do |env|
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
logo_png = nil
|
52
|
+
big = proc do |_env|
|
53
|
+
logo_png ||= IO.binread '../logo.png'
|
54
|
+
[200, { 'Content-Length'.freeze => logo_png.length.to_s , 'Content-Type'.freeze => 'image/png'.freeze}, [logo_png]]
|
55
|
+
end
|
56
|
+
|
51
57
|
case app
|
52
58
|
when 'simple'
|
53
59
|
use Rack::Sendfile
|
54
60
|
run simple
|
55
61
|
when 'hello'
|
56
62
|
run hello
|
63
|
+
when 'big'
|
64
|
+
run big
|
57
65
|
when 'slow'
|
58
66
|
use Rack::Lint
|
59
67
|
run slow
|
data/bin/http-big
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# this will compile Iodine and run an HTTP server "Hello World" example.
|
4
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
5
|
+
puts `rake clean`
|
6
|
+
puts `rake compile`
|
7
|
+
|
8
|
+
require 'benchmark'
|
9
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
10
|
+
require 'bundler/setup'
|
11
|
+
require 'iodine'
|
12
|
+
require 'rack'
|
13
|
+
|
14
|
+
# create the server object and setup any settings we might need.
|
15
|
+
Iodine::Rack
|
16
|
+
Iodine.threads ||= 1
|
17
|
+
Iodine.processes ||= 1 # 4
|
18
|
+
Iodine::Rack.public = '~/Documents/Scratch'
|
19
|
+
count = 2
|
20
|
+
logo_png = IO.binread './logo.png'
|
21
|
+
Iodine::Rack.app = proc { |_env| [200, { 'Content-Length'.freeze => logo_png.length.to_s , 'Content-Type'.freeze => 'image/png'.freeze}, [logo_png]] }
|
22
|
+
puts Iodine::Rack.address
|
23
|
+
Iodine.start
|
24
|
+
|
25
|
+
# puts env.to_a.map { |pair| pair.join(': ') } .join("\n").to_s;
|
26
|
+
|
27
|
+
# puts "Press enter to start (#{Process.pid})"
|
28
|
+
# gets
|
29
|
+
|
30
|
+
###############
|
31
|
+
## for testing:
|
32
|
+
|
33
|
+
# def nag
|
34
|
+
# puts `ab -n 200000 -c 2000 -k http://127.0.0.1:3000/`
|
35
|
+
# sleep 2
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# nag while true
|
39
|
+
#
|
40
|
+
# def nag
|
41
|
+
# puts `wrk -c2000 -d10 -t4 http://localhost:3000/`
|
42
|
+
# sleep 3
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# nag while true
|
46
|
+
|
47
|
+
# ab -n 100000 -c 200 -k http://127.0.0.1:3000/
|
48
|
+
# ab -n 100000 -c 4000 -k http://127.0.0.1:3000/
|
49
|
+
# ab -n 1000000 -c 20000 -k http://127.0.0.1:3000/
|
50
|
+
# ~/ruby/wrk/wrk -c400 -d10 -t12 http://localhost:3000/
|
51
|
+
# wrk -c200 -d4 -t12 http://localhost:3000/
|
52
|
+
# RACK_ENV="production" rackup -p 3000 -s iodine
|
53
|
+
|
54
|
+
# thor --amount 5000 ws://localhost:3000/echo
|
55
|
+
# thor --amount 5000 ws://localhost:3000/broadcast
|
56
|
+
|
57
|
+
# ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
|
58
|
+
# for(i = 0; i< 256; i++) {
|
59
|
+
# ws = new WebSocket("ws://localhost:3000");
|
60
|
+
# ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data); e.target.close(); };
|
61
|
+
# ws.onclose = function(e) {console.log("closed")};
|
62
|
+
# ws.onopen = function(e) {e.target.send("hi");};
|
63
|
+
# };
|
data/exe/iodine
CHANGED
@@ -22,8 +22,9 @@ Available options:
|
|
22
22
|
-v Log responses.
|
23
23
|
-q Never log responses.
|
24
24
|
-warmup Warmup invokes autoloading (lazy loading) during server startup.
|
25
|
-
-
|
26
|
-
-
|
25
|
+
-tout HTTP inactivity connection timeout. Default: 5.
|
26
|
+
-maxbd Maximum Mb per HTTP message (max body size). Default: 50Mib.
|
27
|
+
-maxms Maximum Bytes per Websocket message. Default: 250Kib.
|
27
28
|
-ping Websocket ping interval in seconds. Default: 40 seconds.
|
28
29
|
<filename> Defaults to: config.ru
|
29
30
|
|
@@ -72,6 +73,10 @@ end
|
|
72
73
|
if ARGV.index('-www') && ARGV[ARGV.index('-www') + 1]
|
73
74
|
Iodine::Rack.public = ARGV[ARGV.index('-www') + 1]
|
74
75
|
end
|
76
|
+
if ARGV.index('-tout') && ARGV[ARGV.index('-tout') + 1]
|
77
|
+
Iodine::Rack.timeout = ARGV[ARGV.index('-tout') + 1].to_i
|
78
|
+
puts "WARNNING: Iodine::Rack.timeout set to 0 (ignored, timeout will be ~5 minutes)."
|
79
|
+
end
|
75
80
|
Iodine::Rack.log = true if ARGV.index('-v')
|
76
81
|
Iodine::Rack.log = false if ARGV.index('-q')
|
77
82
|
Iodine.warmup if ARGV.index('-warmup')
|
data/ext/iodine/iodine_core.c
CHANGED
@@ -189,7 +189,7 @@ static void dyn_perform_defer(intptr_t uuid, protocol_s *protocol, void *arg) {
|
|
189
189
|
static void dyn_defer_fallback(intptr_t uuid, void *arg) {
|
190
190
|
(void)(uuid);
|
191
191
|
Registry.remove((VALUE)arg);
|
192
|
-
}
|
192
|
+
}
|
193
193
|
|
194
194
|
/**
|
195
195
|
Runs the required block later (defers the blocks execution).
|
@@ -326,7 +326,7 @@ static VALUE default_on_data(VALUE self) {
|
|
326
326
|
if (!RSTRING_LEN(buff))
|
327
327
|
return Qnil;
|
328
328
|
rb_funcall(self, on_message_func_id, 1, buff);
|
329
|
-
} while (RSTRING_LEN(buff) == rb_str_capacity(buff));
|
329
|
+
} while (RSTRING_LEN(buff) == (ssize_t)rb_str_capacity(buff));
|
330
330
|
return Qnil;
|
331
331
|
}
|
332
332
|
|
@@ -603,6 +603,21 @@ static VALUE iodine_count(VALUE self) {
|
|
603
603
|
/* *****************************************************************************
|
604
604
|
Running the server
|
605
605
|
*/
|
606
|
+
static int sock_io_thread = 0;
|
607
|
+
static void *iodine_io_thread(void *arg) {
|
608
|
+
(void)arg;
|
609
|
+
static const struct timespec tm = {.tv_nsec = 16777216UL};
|
610
|
+
while (sock_io_thread) {
|
611
|
+
sock_flush_all();
|
612
|
+
nanosleep(&tm, NULL);
|
613
|
+
}
|
614
|
+
return NULL;
|
615
|
+
}
|
616
|
+
|
617
|
+
static void iodine_start_io_thread(void) {
|
618
|
+
pthread_t io_thread;
|
619
|
+
pthread_create(&io_thread, NULL, iodine_io_thread, NULL);
|
620
|
+
}
|
606
621
|
|
607
622
|
static void *srv_start_no_gvl(void *_) {
|
608
623
|
(void)(_);
|
@@ -619,16 +634,17 @@ static void *srv_start_no_gvl(void *_) {
|
|
619
634
|
if (threads <= 0)
|
620
635
|
threads = (cpu_count >> 1) ? (cpu_count >> 1) : 1;
|
621
636
|
|
622
|
-
if (cpu_count > 0 &&
|
623
|
-
|
637
|
+
if (cpu_count > 0 && (((size_t)processes << 1) < cpu_count ||
|
638
|
+
(size_t)processes > (cpu_count << 1)))
|
624
639
|
fprintf(
|
625
|
-
stderr,
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
640
|
+
stderr,
|
641
|
+
"* Performance warnning:\n"
|
642
|
+
" - This computer has %lu CPUs available and you'll be "
|
643
|
+
"utilizing %lu processes.\n - %s\n"
|
644
|
+
" - Use the command line option: `-w %lu`\n"
|
645
|
+
" - Or, within Ruby: `Iodine.processes = %lu`\n",
|
630
646
|
cpu_count, (processes ? processes : 1),
|
631
|
-
(processes < cpu_count
|
647
|
+
((size_t)processes < cpu_count
|
632
648
|
? "Some CPUs won't be utilized, inhibiting performance."
|
633
649
|
: "This causes excessive context switches, wasting resources."),
|
634
650
|
cpu_count, cpu_count);
|
@@ -638,7 +654,10 @@ static void *srv_start_no_gvl(void *_) {
|
|
638
654
|
if (threads <= 0)
|
639
655
|
threads = 1;
|
640
656
|
#endif
|
641
|
-
|
657
|
+
sock_io_thread = 1;
|
658
|
+
server_run(.threads = threads, .processes = processes,
|
659
|
+
.on_init = iodine_start_io_thread);
|
660
|
+
sock_io_thread = 0;
|
642
661
|
return NULL;
|
643
662
|
}
|
644
663
|
|
data/lib/iodine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- bin/config.ru
|
101
101
|
- bin/console
|
102
102
|
- bin/echo
|
103
|
+
- bin/http-big
|
103
104
|
- bin/http-hello
|
104
105
|
- bin/http-playground
|
105
106
|
- bin/playground
|
@@ -202,7 +203,7 @@ requirements:
|
|
202
203
|
- Ruby >= 2.2.2 required for Rack.
|
203
204
|
- Ruby >= 2.3.0 recommended.
|
204
205
|
rubyforge_project:
|
205
|
-
rubygems_version: 2.6.
|
206
|
+
rubygems_version: 2.6.11
|
206
207
|
signing_key:
|
207
208
|
specification_version: 4
|
208
209
|
summary: Iodine - leveraging C for Ruby servers.
|