iodine 0.7.40 → 0.7.41

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e0b09518eec222b16c1740793a825c123672f3f027c7182c7fc021c9894136d
4
- data.tar.gz: 0cf02ed5b0a11526dadf984f7d58accc434c896aa011ed3f3319f418df80c73b
3
+ metadata.gz: 03af29c680fee3cd7b70b4a9fbc0f370b42a763f83f4422cc0f1cae296b95f1c
4
+ data.tar.gz: b6e25d8cc33dd955989ae6c8f6bf18d45f84dad42887eff22f39c68aada56f02
5
5
  SHA512:
6
- metadata.gz: 6bbcc4ffb71aaed9efef0549b91b4da786672b000ec3b14e87106ad65421a28fe36b415ef0a0f02b9da1620c7ef057abba50e93e88bea37bc82c26a2728fd793
7
- data.tar.gz: bfcd03eda1096833ab4315935f435f9891349830db493a74d570c7830505a4e43d5b6c6f0d143273ddb83a076174183888b4f8173dc421c23e12a645edf2006b
6
+ metadata.gz: b4eab8d5f7309dd8845d4f6c8052935dbd8145201c4820786ae000e895277883765c1dd628c1e053816b50a1d7c002180f6b4e0a5833e60d76277dab8ecf81b1
7
+ data.tar.gz: f90eb620cf2a9aaf7c943fe981e829f698cb1e8fc176ad8ad778df2c36c5eb026314522d428bee8058915e95f9ed3750ed078931193b81b0dec062e27eb569c2
@@ -1,4 +1,7 @@
1
1
  language: ruby
2
+ arch:
3
+ - amd64
4
+ - arm64
2
5
  os:
3
6
  - linux
4
7
  # - osx
@@ -6,6 +9,7 @@ before_install:
6
9
  - gem install bundler -v 1.10.6
7
10
  - bundle install
8
11
  rvm:
12
+ - 2.7.1
9
13
  - 2.6.5
10
14
  - 2.5.7
11
15
  - 2.4.9
@@ -14,7 +18,7 @@ rvm:
14
18
  notifications:
15
19
  email: false
16
20
  sudo: required
17
- dist: trusty
21
+ dist: xenial
18
22
  addons:
19
23
  apt:
20
24
  sources:
@@ -24,8 +28,5 @@ addons:
24
28
  script:
25
29
  - echo CFLAGS = $CFLAGS
26
30
  - echo cflags = $cflags
27
- - bundle exec rake compile
31
+ - bundle exec rake install
28
32
  - env VERBOSE=1 bundle exec rspec --format documentation
29
- - gem uninstall -x iodine
30
- - rake build
31
- - find pkg/iodine-*.gem -exec gem install -V {} +
@@ -6,6 +6,12 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+ #### Change log v.0.7.41 (2020-07-24)
10
+
11
+ **Fix**: Hot Restart failed because listening sockets were cleared away. Credit to Néstor Coppi (@Shelvak) for exposing issue #97.
12
+
13
+ **Fix**: CLI argument parsing is now only active when using the iodine CLI (or if defining `IODINE_PARSE_CLI` before requiring `iodine`). Credit to Aldis Berjoza (@graudeejs) for exposing issue #96.
14
+
9
15
  #### Change log v.0.7.40 (2020-05-23)
10
16
 
11
17
  **Fix**: fixed TLS logging and performance issues exposed by Franck Gille (@fgi) in issue #93.
data/README.md CHANGED
@@ -19,14 +19,15 @@ Iodine includes native support for:
19
19
  * Pub/Sub (with optional Redis Pub/Sub scaling);
20
20
  * Fast(!) builtin Mustache template engine.
21
21
  * Static file service (with automatic `gzip` support for pre-compressed assets);
22
+ * Optimized Logging to `stderr`.
22
23
  * Asynchronous event scheduling and timers;
23
24
  * HTTP/1.1 keep-alive and pipelining;
25
+ * Heap Fragmentation Protection.
24
26
  * TLS 1.2 and above (Requires OpenSSL >= 1.1.0);
25
27
  * TCP/IP server and client connectivity;
26
28
  * Unix Socket server and client connectivity;
27
- * Hot Restart (using the USR1 signal);
29
+ * Hot Restart (using the USR1 signal and without hot deployment);
28
30
  * Custom protocol authoring;
29
- * Optimized Logging to `stderr`.
30
31
  * [Sequel](https://github.com/jeremyevans/sequel) and ActiveRecord forking protection.
31
32
  * and more!
32
33
 
@@ -48,6 +49,10 @@ With `Iodine.listen service: :http` it's possible to run multiple HTTP applicati
48
49
 
49
50
  Iodine also supports native process cluster Pub/Sub and a native RedisEngine to easily scale iodine's Pub/Sub horizontally.
50
51
 
52
+ ### Known Issues and Reporting Issues
53
+
54
+ See the [GitHub Open Issues](https://github.com/boazsegev/iodine/issues) list for known issues and to report new issues.
55
+
51
56
  ### Installing and Running Iodine
52
57
 
53
58
  Install iodine on any Linux / BSD / macOS system using:
@@ -70,6 +75,8 @@ bundler exec iodine
70
75
 
71
76
  #### Installing with SSL/TLS
72
77
 
78
+ **Note**: iodine has known issues with the TLS/SSL support. TLS/SSL should **NOT** be used in production (see issues #95 and #94).
79
+
73
80
  Make sure to update OpenSSL to the latest version **before installing Ruby** (`rbenv` should do this automatically).
74
81
 
75
82
  To avoid name resolution conflicts, iodine will bind to the same OpenSSL version Ruby is bound to. To use SSL/TLS this should be OpenSSL >= 1.1.0 or LibreSSL >= 2.7.4.
@@ -87,9 +94,7 @@ Confirmed OpenSSL to be version 1.1.0 or above (OpenSSL 1.1.0j 20 Nov 2018)...
87
94
  ...
88
95
  ```
89
96
 
90
- **KNOWN ISSUE:**
91
-
92
- The installation script tests for OpenSSL 1.1.0 and above. However, this testing approach sometimes provides false positives. If TLS isn't required, install with `NO_SSL=1`. i.e.:
97
+ The installation script tests for OpenSSL 1.1.0 and above. However, this testing approach sometimes provides false positives. **If TLS isn't required, install with `NO_SSL=1`**. i.e.:
93
98
 
94
99
  ```bash
95
100
  NO_SSL=1 bundler exec iodine
@@ -110,17 +115,19 @@ On Rails:
110
115
  if(defined?(Iodine))
111
116
  Iodine.threads = ENV.fetch("RAILS_MAX_THREADS", 5).to_i if Iodine.threads.zero?
112
117
  Iodine.workers = ENV.fetch("WEB_CONCURRENCY", 2).to_i if Iodine.workers.zero?
113
- Iodine::DEFAULT_SETTINGS[:port] = ENV.fetch("PORT") if ENV.fetch("PORT")
118
+ Iodine::DEFAULT_SETTINGS[:port] ||= ENV.fetch("PORT") if ENV.fetch("PORT")
114
119
  end
115
120
  ```
116
121
 
117
122
  When using native WebSockets with Rails, middle-ware is probably the best approach. A guide for this approach will, hopefully, get published in the future.
118
123
 
124
+ **Note**: command-line instructions (CLI) should be the preferred way for configuring iodine, allowing for code-less configuration updates.
125
+
119
126
  ### Optimizing Iodine's Concurrency
120
127
 
121
128
  To get the most out of iodine, consider the amount of CPU cores available and the concurrency level the application requires.
122
129
 
123
- Iodine will calculate, when possible, a good enough default concurrency model. See if this works for your application or customize according to the application's needs.
130
+ Iodine will calculate, when possible, a good enough default concurrency model for fast applications. See if this works for your application or customize according to the application's needs.
124
131
 
125
132
  Command line arguments allow easy access to different options, including concurrency levels. i.e., to set up 16 threads and 4 processes:
126
133
 
@@ -136,13 +143,19 @@ export WORKERS=-1 # negative values are fractions of CPU cores.
136
143
  bundler exec iodine -p $PORT
137
144
  ```
138
145
 
146
+ Negative values are evaluated as "CPU Cores / abs(Value)". i.e., on an 8 core CPU machine, this will produce 4 worker processes with 2 threads per worker:
147
+
148
+ ```bash
149
+ bundler exec iodine -p $PORT -t 2 -w -2
150
+ ```
151
+
139
152
  ### Heap Fragmentation Protection
140
153
 
141
154
  Iodine includes a fast, network oriented, custom memory allocator, optimizing away some of the work usually placed on the Ruby Garbage Collector (GC).
142
155
 
143
156
  This approach helps to minimize heap fragmentation for long running processes, by grouping many short-lived objects into a common memory space.
144
157
 
145
- It's still recommended to consider [jemalloc](http://jemalloc.net) or other allocators that also help mitigate heap fragmentation issues.
158
+ It is still recommended to consider [jemalloc](http://jemalloc.net) or other allocators that also help mitigate heap fragmentation issues.
146
159
 
147
160
  ### Static file serving support
148
161
 
@@ -435,11 +448,11 @@ Iodine.connect url: "wss://echo.websocket.org", handler: EchoClient.new, ping: 4
435
448
  Iodine.start
436
449
  ```
437
450
 
438
- ### TLS 1.2 support
451
+ ### TLS >= 1.2 support
439
452
 
440
453
  > Requires OpenSSL >= `1.1.0`. On Heroku, requires `heroku-18`.
441
454
 
442
- Iodine supports secure connections fore TLS version 1.2 and up (depending on the OpenSSL version).
455
+ Iodine supports secure connections fore TLS version 1.2 **and up** (depending on the OpenSSL version).
443
456
 
444
457
  A self signed certificate is available using the `-tls` flag from the command-line.
445
458
 
@@ -480,31 +493,11 @@ run APP
480
493
 
481
494
  ### How does it compare to other servers?
482
495
 
483
- The honest answer is "I don't know". I recommend that you perform your own tests.
484
-
485
- In my tests, pitching Iodine against Puma, Iodine was anywhere between x1.5 and x7 faster than Puma (depending on use-case). such a big difference is suspect and I recommend that you test it yourself.
496
+ In my tests, pitching Iodine against Puma, Iodine was anywhere between x1.5 and more than x10 faster than Puma (depending on use-case and settings).
486
497
 
487
- Also, performing benchmarks on a single machine isn't very reliable... but it's all I've got.
498
+ Such a big difference is suspect and I recommend that you test it yourself - even better if you test performance using your own application and a number of possible different settings (how many threads per CPU core? how many worker processes? middleware vs. server request logging, etc').
488
499
 
489
- When benchmarking with `wrk`, on the same local machine with similar settings for both Puma and Iodine (4 workers, 16 threads each, 200 concurrent connections), I calculated Iodine to be x1.52 faster::
490
-
491
- * Iodine performed at 74,786.27 req/sec, consuming ~68.4Mb of memory.
492
-
493
- * Puma performed at 48,994.59 req/sec, consuming ~79.6Mb of memory.
494
-
495
- When benchmarking using a VM (crossing machine boundaries, 16 threads, 4 workers, 200 concurrent connections), I calculated Iodine to be x2.3 faster:
496
-
497
- * Iodine performed at 23,559.56 req/sec, consuming ~88.8Mb of memory.
498
-
499
- * Puma performed at 9,935.31 req/sec, consuming ~84.0Mb of memory.
500
-
501
- When benchmarking using a VM (crossing machine boundaries, single thread, single worker, 200 concurrent connections), I calculated Iodine to be x7.3 faster:
502
-
503
- * Iodine performed at 18,444.31 req/sec, consuming ~25.6Mb of memory.
504
-
505
- * Puma performed at 2,521.56 req/sec, consuming ~27.5Mb of memory.
506
-
507
- I have doubts about my own benchmarks and I recommend benchmarking the performance for yourself using `wrk` or `ab`:
500
+ I recommend benchmarking the performance for yourself using `wrk` or `ab`:
508
501
 
509
502
  ```bash
510
503
  $ wrk -c200 -d4 -t2 http://localhost:3000/
@@ -512,7 +505,7 @@ $ wrk -c200 -d4 -t2 http://localhost:3000/
512
505
  $ ab -n 100000 -c 200 -k http://127.0.0.1:3000/
513
506
  ```
514
507
 
515
- Create a simple `config.ru` file with a hello world app:
508
+ The best application to use for benchmarking is your actual application. Or, you could create a simple `config.ru` file with a __hello world__ app:
516
509
 
517
510
  ```ruby
518
511
  App = Proc.new do |env|
@@ -525,17 +518,21 @@ end
525
518
  run App
526
519
  ```
527
520
 
528
- Then start comparing servers. Here are the settings I used to compare iodine and Puma (4 processes, 16 threads):
521
+ Then start comparing servers. Here are the settings I used to compare iodine and Puma (4 processes, 4 threads):
529
522
 
530
523
  ```bash
531
- $ RACK_ENV=production iodine -p 3000 -t 16 -w 4
524
+ $ RACK_ENV=production iodine -p 3000 -t 4 -w 4
532
525
  # vs.
533
- $ RACK_ENV=production puma -p 3000 -t 16 -w 4
526
+ $ RACK_ENV=production puma -p 3000 -t 4 -w 4
534
527
  # Review the `iodine -?` help for more command line options.
535
528
  ```
536
529
 
537
530
  It's recommended that the servers (Iodine/Puma) and the client (`wrk`/`ab`) run on separate machines.
538
531
 
532
+ It is worth noting that iodine can also speed up logging by replacing the logging middleware with `iodine -v`. This approach uses less memory and improves performance at the expense of fuzzy timing and some string caching.
533
+
534
+ On my machine, testing with the logging functionality enabled, iodine was more then 10 times faster than puma (60.9K req/sec vs. 5.3K req/sec)
535
+
539
536
  ### A few notes
540
537
 
541
538
  Iodine's upgrade / callback design has a number of benefits, some of them related to better IO handling, resource optimization (no need for two IO polling systems), etc. This also allows us to use middleware without interfering with connection upgrades and provides backwards compatibility.
data/exe/iodine CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+ IODINE_PARSE_CLI = true
3
4
  require 'iodine'
4
5
 
5
6
  # Load Rack if available (assume it will be used).
@@ -36,6 +36,12 @@ Feel free to copy, use and enjoy according to the license provided.
36
36
 
37
37
  #include <arpa/inet.h>
38
38
 
39
+ #if HAVE_OPENSSL
40
+ #include <openssl/bio.h>
41
+ #include <openssl/err.h>
42
+ #include <openssl/ssl.h>
43
+ #endif
44
+
39
45
  /* force poll for testing? */
40
46
  #ifndef FIO_ENGINE_POLL
41
47
  #define FIO_ENGINE_POLL 0
@@ -3492,11 +3498,13 @@ static void fio_on_fork(void) {
3492
3498
  fio_poll_init();
3493
3499
  fio_state_callback_on_fork();
3494
3500
 
3501
+ /* don't pass open connections belonging to the parent onto the child. */
3495
3502
  const size_t limit = fio_data->capa;
3496
3503
  for (size_t i = 0; i < limit; ++i) {
3497
3504
  fd_data(i).sock_lock = FIO_LOCK_INIT;
3498
3505
  fd_data(i).protocol_lock = FIO_LOCK_INIT;
3499
- if (fd_data(i).protocol) {
3506
+ if (fd_data(i).protocol && fd_data(i).open) {
3507
+ /* open without protocol might be waiting for the child (listening) */
3500
3508
  fd_data(i).protocol->rsv = 0;
3501
3509
  fio_force_close(fd2uuid(i));
3502
3510
  }
@@ -3678,8 +3686,9 @@ static void fio_review_timeout(void *arg, void *ignr) {
3678
3686
  unlock:
3679
3687
  protocol_unlock(tmp, FIO_PR_LOCK_STATE);
3680
3688
  } else {
3681
- /* open FD but no protocol? */
3682
- fio_close(fd2uuid(fd));
3689
+ /* open FD but no protocol? RW hook thing or listening sockets? */
3690
+ if (fd_data(fd).rw_hooks != &FIO_DEFAULT_RW_HOOKS)
3691
+ fio_close(fd2uuid(fd));
3683
3692
  }
3684
3693
  finish:
3685
3694
  do {
@@ -3908,16 +3917,22 @@ void fio_start FIO_IGNORE_MACRO(struct fio_start_args args) {
3908
3917
  fio_data->is_worker = 0;
3909
3918
 
3910
3919
  fio_state_callback_force(FIO_CALL_PRE_START);
3911
-
3912
3920
  FIO_LOG_INFO(
3913
3921
  "Server is running %u %s X %u %s with facil.io " FIO_VERSION_STRING
3914
3922
  " (%s)\n"
3923
+ #if HAVE_OPENSSL
3924
+ "* Linked to %s\n"
3925
+ #endif
3915
3926
  "* Detected capacity: %d open file limit\n"
3916
3927
  "* Root pid: %d\n"
3917
3928
  "* Press ^C to stop\n",
3918
3929
  fio_data->workers, fio_data->workers > 1 ? "workers" : "worker",
3919
3930
  fio_data->threads, fio_data->threads > 1 ? "threads" : "thread",
3920
- fio_engine(), fio_data->capa, (int)fio_data->parent);
3931
+ fio_engine(),
3932
+ #if HAVE_OPENSSL
3933
+ OpenSSL_version(0),
3934
+ #endif
3935
+ fio_data->capa, (int)fio_data->parent);
3921
3936
 
3922
3937
  if (args.workers > 1) {
3923
3938
  for (int i = 0; i < args.workers && fio_data->active; ++i) {
@@ -178,7 +178,7 @@ Iodine.on_state(:after_fork) do
178
178
  end
179
179
 
180
180
  ### Parse CLI for default HTTP settings
181
- Iodine::Base::CLI.parse
181
+ Iodine::Base::CLI.parse if defined?(IODINE_PARSE_CLI) && IODINE_PARSE_CLI
182
182
 
183
183
  ### Set default port (if missing)
184
184
  Iodine::DEFAULT_SETTINGS[:port] ||= (ENV["PORT"] || "3000")
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.7.40'.freeze
2
+ VERSION = '0.7.41'.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.7.40
4
+ version: 0.7.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-23 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -243,7 +243,7 @@ licenses:
243
243
  metadata:
244
244
  allowed_push_host: https://rubygems.org
245
245
  post_install_message: |-
246
- Thank you for installing Iodine 0.7.40.
246
+ Thank you for installing Iodine 0.7.41.
247
247
  Remember: if iodine supports your business, it's only fair to give value back (code contributions / donations).
248
248
  rdoc_options: []
249
249
  require_paths: