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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94ddb42ee5c0ca01c01a252da1a13889165f6bfc
4
- data.tar.gz: 701269ce567cd8c0206a0503d9c75764788bddee
3
+ metadata.gz: de923f79329ea2c150786d10000b43b6378612e3
4
+ data.tar.gz: 97749ca95384e2e5b0487c4bfda183690440257c
5
5
  SHA512:
6
- metadata.gz: 7e6ff2fe5ac88b5343b33df08ed0c21833e48a1c49f83603dd899b78fa3ec73b3a681268bf71d321c4d15248fec25b46db6a2eba7d2fba992c8478132e4f0d8b
7
- data.tar.gz: 8b8e9b38b31b14b68f247eedef46eae9adf9d3a3de9c2be9d997e327508e9b83077ab9d9bf015f62a08e053c92e7e3beba8d4a5bc7c16218732792b684eb7e89
6
+ metadata.gz: 40b2d878c483d077421eab48b4be2b02f6c3bb1ebf32cd43c9fc6007fdae110828df6b6d02867d54bf6ae524e3762dd8d9f95277712038a64e1727f00e3a1153
7
+ data.tar.gz: 289d7f82bd5f2a67621ada01dfc56143ba62c5dbeafcd0b4c5a544a9ba7c992b2c4dff5322b7b0fe21e656f3b9913716d8b523d0c708325028c54fc2a2cfa0bf
@@ -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
 
@@ -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 = 'hello'
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
@@ -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
- -maxbd Maximum Mb per HTTP message (max body size). Default: ~50Mb.
26
- -maxms Maximum Bytes per Websocket message. Default: ~250Kb.
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')
@@ -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
- ((processes << 1) < cpu_count || processes > (cpu_count << 1)))
637
+ if (cpu_count > 0 && (((size_t)processes << 1) < cpu_count ||
638
+ (size_t)processes > (cpu_count << 1)))
624
639
  fprintf(
625
- stderr, "* Performance warnning:\n"
626
- " - This computer has %lu CPUs available and you'll be "
627
- "utilizing %lu processes.\n - %s\n"
628
- " - Use the command line option: `-w %lu`\n"
629
- " - Or, within Ruby: `Iodine.processes = %lu`\n",
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
- server_run(.threads = threads, .processes = processes);
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
 
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.2.16'.freeze
2
+ VERSION = '0.2.17'.freeze
3
3
  end
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.16
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-04-17 00:00:00.000000000 Z
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.8
206
+ rubygems_version: 2.6.11
206
207
  signing_key:
207
208
  specification_version: 4
208
209
  summary: Iodine - leveraging C for Ruby servers.