iodine 0.7.9 → 0.7.10
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/.travis.yml +8 -2
- data/CHANGELOG.md +14 -0
- data/README.md +85 -29
- data/{examples → bin}/info.md +0 -0
- data/bin/{mustache.rb → mustache_bench.rb} +0 -0
- data/examples/shootout.ru +4 -4
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/fio.c +738 -549
- data/ext/iodine/fio.h +4 -5
- data/ext/iodine/fiobj_mustache.c +1 -1
- data/ext/iodine/fiobj_numbers.c +3 -3
- data/ext/iodine/http.c +15 -14
- data/ext/iodine/http1.c +6 -6
- data/ext/iodine/http1_parser.c +3 -3
- data/ext/iodine/http_internal.c +3 -3
- data/ext/iodine/http_internal.h +1 -1
- data/ext/iodine/iodine.c +7 -8
- data/ext/iodine/iodine_connection.c +48 -8
- data/ext/iodine/iodine_defer.c +7 -7
- data/ext/iodine/iodine_mustache.c +1 -1
- data/ext/iodine/redis_engine.c +4 -4
- data/ext/iodine/websockets.c +41 -22
- data/ext/iodine/websockets.h +13 -12
- data/iodine.gemspec +0 -2
- data/lib/iodine.rb +4 -0
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +2 -4
- metadata +5 -39
- data/bin/config.ru +0 -97
- data/bin/echo +0 -46
- data/bin/http-big +0 -63
- data/bin/http-hello +0 -62
- data/bin/http-playground +0 -124
- data/bin/playground +0 -62
- data/bin/raw-rbhttp +0 -38
- data/bin/raw-rbhttp-em +0 -63
- data/bin/raw_broadcast +0 -64
- data/bin/test_with_faye +0 -44
- data/bin/updated api +0 -113
- data/bin/ws-broadcast +0 -106
- data/bin/ws-echo +0 -117
- data/examples/test_template.mustache +0 -16
@@ -65,7 +65,7 @@ b = a.map {|s| s.length }
|
|
65
65
|
puts "static char *html_escape_strs[] = {", a.to_s.slice(1..-2) ,"};",
|
66
66
|
"static uint8_t html_escape_len[] = {", b.to_s.slice(1..-2),"};"
|
67
67
|
*/
|
68
|
-
static char *html_escape_strs[] = {
|
68
|
+
static const char *html_escape_strs[] = {
|
69
69
|
"�", "", "", "", "", "", "",
|
70
70
|
"", "", "	", "
", "", "", "
",
|
71
71
|
"", "", "", "", "", "", "",
|
data/ext/iodine/redis_engine.c
CHANGED
@@ -359,8 +359,8 @@ static void resp_on_sub_message(struct redis_engine_internal_s *i, FIOBJ msg) {
|
|
359
359
|
if (FIOBJ_TYPE(msg) != FIOBJ_T_STRING || fiobj_obj2cstr(msg).len != 4 ||
|
360
360
|
fiobj_obj2cstr(msg).data[0] != 'P') {
|
361
361
|
FIO_LOG_WARNING("(redis) unexpected data format in "
|
362
|
-
"subscription stream
|
363
|
-
|
362
|
+
"subscription stream:\n %s",
|
363
|
+
fiobj_obj2cstr(msg).data);
|
364
364
|
}
|
365
365
|
} else {
|
366
366
|
// FIOBJ *ary = fiobj_ary2ptr(msg);
|
@@ -840,10 +840,10 @@ FIO_IGNORE_MACRO(struct redis_engine_create_args args) {
|
|
840
840
|
}
|
841
841
|
|
842
842
|
if (!args.address.data || !args.address.len) {
|
843
|
-
args.address = (fio_str_info_s){.len = 9, .data = "localhost"};
|
843
|
+
args.address = (fio_str_info_s){.len = 9, .data = (char *)"localhost"};
|
844
844
|
}
|
845
845
|
if (!args.port.data || !args.port.len) {
|
846
|
-
args.port = (fio_str_info_s){.len = 4, .data = "6379"};
|
846
|
+
args.port = (fio_str_info_s){.len = 4, .data = (char *)"6379"};
|
847
847
|
}
|
848
848
|
redis_engine_s *r =
|
849
849
|
fio_malloc(sizeof(*r) + args.port.len + 1 + args.address.len + 1 +
|
data/ext/iodine/websockets.c
CHANGED
@@ -526,15 +526,6 @@ typedef struct {
|
|
526
526
|
void *udata;
|
527
527
|
} websocket_sub_data_s;
|
528
528
|
|
529
|
-
static void websocket_on_unsubscribe(void *u1, void *u2) {
|
530
|
-
websocket_sub_data_s *d = u2;
|
531
|
-
if (d->on_unsubscribe) {
|
532
|
-
d->on_unsubscribe(d->udata);
|
533
|
-
}
|
534
|
-
free(d);
|
535
|
-
(void)u1;
|
536
|
-
}
|
537
|
-
|
538
529
|
static inline void websocket_on_pubsub_message_direct_internal(fio_msg_s *msg,
|
539
530
|
uint8_t txt) {
|
540
531
|
fio_protocol_s *pr =
|
@@ -563,7 +554,6 @@ static inline void websocket_on_pubsub_message_direct_internal(fio_msg_s *msg,
|
|
563
554
|
break;
|
564
555
|
}
|
565
556
|
if (pre_wrapped) {
|
566
|
-
// fprintf(stderr, "INFO: WebSocket Pub/Sub optimized for broadcast\n");
|
567
557
|
fiobj_send_free((intptr_t)msg->udata1, fiobj_dup(pre_wrapped));
|
568
558
|
goto finish;
|
569
559
|
}
|
@@ -607,6 +597,25 @@ static void websocket_on_pubsub_message(fio_msg_s *msg) {
|
|
607
597
|
fio_protocol_unlock(pr, FIO_PR_LOCK_TASK);
|
608
598
|
}
|
609
599
|
|
600
|
+
static void websocket_on_unsubscribe(void *u1, void *u2) {
|
601
|
+
websocket_sub_data_s *d = u2;
|
602
|
+
if (d->on_unsubscribe) {
|
603
|
+
d->on_unsubscribe(d->udata);
|
604
|
+
}
|
605
|
+
|
606
|
+
if ((intptr_t)d->on_message == (intptr_t)WEBSOCKET_OPTIMIZE_PUBSUB) {
|
607
|
+
websocket_optimize4broadcasts(WEBSOCKET_OPTIMIZE_PUBSUB, 0);
|
608
|
+
} else if ((intptr_t)d->on_message ==
|
609
|
+
(intptr_t)WEBSOCKET_OPTIMIZE_PUBSUB_TEXT) {
|
610
|
+
websocket_optimize4broadcasts(WEBSOCKET_OPTIMIZE_PUBSUB_TEXT, 0);
|
611
|
+
} else if ((intptr_t)d->on_message ==
|
612
|
+
(intptr_t)WEBSOCKET_OPTIMIZE_PUBSUB_BINARY) {
|
613
|
+
websocket_optimize4broadcasts(WEBSOCKET_OPTIMIZE_PUBSUB_BINARY, 0);
|
614
|
+
}
|
615
|
+
free(d);
|
616
|
+
(void)u1;
|
617
|
+
}
|
618
|
+
|
610
619
|
/**
|
611
620
|
* Returns a subscription ID on success and 0 on failure.
|
612
621
|
*/
|
@@ -621,18 +630,28 @@ uintptr_t websocket_subscribe(struct websocket_subscribe_s args) {
|
|
621
630
|
.on_message = args.on_message,
|
622
631
|
.on_unsubscribe = args.on_unsubscribe,
|
623
632
|
};
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
633
|
+
void (*handler)(fio_msg_s *) = websocket_on_pubsub_message;
|
634
|
+
if (!args.on_message) {
|
635
|
+
intptr_t br_type;
|
636
|
+
if (args.force_binary) {
|
637
|
+
br_type = WEBSOCKET_OPTIMIZE_PUBSUB_BINARY;
|
638
|
+
handler = websocket_on_pubsub_message_direct_bin;
|
639
|
+
} else if (args.force_text) {
|
640
|
+
br_type = WEBSOCKET_OPTIMIZE_PUBSUB_TEXT;
|
641
|
+
handler = websocket_on_pubsub_message_direct_txt;
|
642
|
+
} else {
|
643
|
+
br_type = WEBSOCKET_OPTIMIZE_PUBSUB;
|
644
|
+
handler = websocket_on_pubsub_message_direct;
|
645
|
+
}
|
646
|
+
websocket_optimize4broadcasts(br_type, 1);
|
647
|
+
d->on_message =
|
648
|
+
(void (*)(ws_s *, fio_str_info_s, fio_str_info_s, void *))br_type;
|
649
|
+
}
|
650
|
+
subscription_s *sub =
|
651
|
+
fio_subscribe(.channel = args.channel, .match = args.match,
|
652
|
+
.on_unsubscribe = websocket_on_unsubscribe,
|
653
|
+
.on_message = handler, .udata1 = (void *)args.ws->fd,
|
654
|
+
.udata2 = d);
|
636
655
|
if (!sub) {
|
637
656
|
/* don't free `d`, return (`d` freed by fio_subscribe) */
|
638
657
|
return 0;
|
data/ext/iodine/websockets.h
CHANGED
@@ -152,19 +152,11 @@ void websocket_unsubscribe(ws_s *ws, uintptr_t subscription_id);
|
|
152
152
|
/**
|
153
153
|
* Enables (or disables) broadcast optimizations.
|
154
154
|
*
|
155
|
-
*
|
156
|
-
*
|
157
|
-
*
|
158
|
-
* majority of the messages are meant for a single recipient (or multiple
|
159
|
-
* callback recipients) and only some are expected to be directly transmitted to
|
160
|
-
* a group.
|
155
|
+
* This is performed automatically by the `websocket_subscribe` function.
|
156
|
+
* However, this function is provided for enabling the pub/sub metadata based
|
157
|
+
* optimizations for external connections / subscriptions.
|
161
158
|
*
|
162
|
-
*
|
163
|
-
* 3 clients (on average), certain optimizations can be made to improve memory
|
164
|
-
* consumption (minimize duplication or WebSocket network data).
|
165
|
-
*
|
166
|
-
* This function allows enablement (or disablement) of these optimizations.
|
167
|
-
* These optimizations include:
|
159
|
+
* This function allows enablement (or disablement) of these optimizations:
|
168
160
|
*
|
169
161
|
* * WEBSOCKET_OPTIMIZE_PUBSUB - optimize all direct transmission messages,
|
170
162
|
* best attempt to detect Text vs. Binary data.
|
@@ -174,6 +166,15 @@ void websocket_unsubscribe(ws_s *ws, uintptr_t subscription_id);
|
|
174
166
|
* Note: to disable an optimization it should be disabled the same amount of
|
175
167
|
* times it was enabled - multiple optimization enablements for the same type
|
176
168
|
* are merged, but reference counted (disabled when reference is zero).
|
169
|
+
*
|
170
|
+
* Note2: The pub/sub metadata type ID will match the optimnization type
|
171
|
+
* requested (i.e., `WEBSOCKET_OPTIMIZE_PUBSUB`) and the optimized data is a
|
172
|
+
* FIOBJ String containing a pre-encoded WebSocket packet ready to be sent.
|
173
|
+
* i.e.:
|
174
|
+
*
|
175
|
+
* FIOBJ pre_wrapped = (FIOBJ)fio_message_metadata(msg,
|
176
|
+
* WEBSOCKET_OPTIMIZE_PUBSUB);
|
177
|
+
* fiobj_send_free((intptr_t)msg->udata1, fiobj_dup(pre_wrapped));
|
177
178
|
*/
|
178
179
|
void websocket_optimize4broadcasts(intptr_t type, int enable);
|
179
180
|
|
data/iodine.gemspec
CHANGED
@@ -31,8 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.required_ruby_version = '>= 2.2.2' # Because earlier versions had been discontinued
|
33
33
|
|
34
|
-
spec.add_dependency 'rack', '>= 1.0', '< 3.0'
|
35
|
-
|
36
34
|
spec.requirements << 'A Unix based system: Linux / macOS / BSD.'
|
37
35
|
spec.requirements << 'An updated C compiler.'
|
38
36
|
spec.requirements << 'Ruby >= 2.2.2 required for Rack 2.'
|
data/lib/iodine.rb
CHANGED
@@ -63,6 +63,10 @@ module Iodine
|
|
63
63
|
#
|
64
64
|
# This is recommended, see {Iodine::Rack::Utils} for details.
|
65
65
|
def self.patch_rack
|
66
|
+
begin
|
67
|
+
require 'rack'
|
68
|
+
rescue LoadError => e
|
69
|
+
end
|
66
70
|
::Rack::Utils.class_eval do
|
67
71
|
Iodine::Base::MonkeyPatch::RackUtils.methods(false).each do |m|
|
68
72
|
::Rack::Utils.define_singleton_method(m,
|
data/lib/iodine/version.rb
CHANGED
data/lib/rack/handler/iodine.rb
CHANGED
@@ -24,13 +24,11 @@ ENV['RACK_HANDLER'] = 'iodine'
|
|
24
24
|
begin
|
25
25
|
require 'rack/handler' unless defined?(Rack::Handler)
|
26
26
|
Rack::Handler::WEBrick = ::Iodine::Rack # Rack::Handler.get(:iodine)
|
27
|
-
rescue
|
28
|
-
|
27
|
+
rescue LoadError
|
29
28
|
end
|
30
29
|
|
31
30
|
begin
|
32
31
|
::Rack::Handler.register('iodine', 'Iodine::Rack') if defined?(::Rack::Handler)
|
33
32
|
::Rack::Handler.register('Iodine', 'Iodine::Rack') if defined?(::Rack::Handler)
|
34
|
-
rescue
|
35
|
-
|
33
|
+
rescue StandardError
|
36
34
|
end
|
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rack
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '3.0'
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.0'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '3.0'
|
33
13
|
- !ruby/object:Gem::Dependency
|
34
14
|
name: bundler
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,34 +111,20 @@ files:
|
|
131
111
|
- Rakefile
|
132
112
|
- SPEC-PubSub-Draft.md
|
133
113
|
- SPEC-Websocket-Draft.md
|
134
|
-
- bin/config.ru
|
135
114
|
- bin/console
|
136
|
-
- bin/
|
137
|
-
- bin/
|
138
|
-
- bin/http-hello
|
139
|
-
- bin/http-playground
|
140
|
-
- bin/mustache.rb
|
141
|
-
- bin/playground
|
115
|
+
- bin/info.md
|
116
|
+
- bin/mustache_bench.rb
|
142
117
|
- bin/poc/Gemfile.lock
|
143
118
|
- bin/poc/README.md
|
144
119
|
- bin/poc/config.ru
|
145
120
|
- bin/poc/gemfile
|
146
121
|
- bin/poc/www/index.html
|
147
|
-
- bin/raw-rbhttp
|
148
|
-
- bin/raw-rbhttp-em
|
149
|
-
- bin/raw_broadcast
|
150
|
-
- bin/test_with_faye
|
151
|
-
- bin/updated api
|
152
|
-
- bin/ws-broadcast
|
153
|
-
- bin/ws-echo
|
154
122
|
- examples/config.ru
|
155
123
|
- examples/echo.ru
|
156
124
|
- examples/hello.ru
|
157
|
-
- examples/info.md
|
158
125
|
- examples/pubsub_engine.ru
|
159
126
|
- examples/redis.ru
|
160
127
|
- examples/shootout.ru
|
161
|
-
- examples/test_template.mustache
|
162
128
|
- exe/iodine
|
163
129
|
- ext/iodine/extconf.rb
|
164
130
|
- ext/iodine/fio.c
|
@@ -244,7 +210,7 @@ licenses:
|
|
244
210
|
- MIT
|
245
211
|
metadata:
|
246
212
|
allowed_push_host: https://rubygems.org
|
247
|
-
post_install_message: 'Thank you for installing Iodine 0.7.
|
213
|
+
post_install_message: 'Thank you for installing Iodine 0.7.10.
|
248
214
|
|
249
215
|
'
|
250
216
|
rdoc_options: []
|
data/bin/config.ru
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
require 'rack/sendfile'
|
3
|
-
require 'rack/lint'
|
4
|
-
|
5
|
-
# There are a number of possible applications to run in this file,
|
6
|
-
# because I use it to test stuff.
|
7
|
-
#
|
8
|
-
# This value (app) sets which of the different applications will run.
|
9
|
-
#
|
10
|
-
# Valid values are "hello", "slow" (debugs env values), "simple"
|
11
|
-
app = 'hello'
|
12
|
-
|
13
|
-
# This is a simple Hello World Rack application, for benchmarking.
|
14
|
-
HELLO_RESPONSE = [200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
15
|
-
'Content-Length'.freeze => '16'.freeze }.freeze,
|
16
|
-
['Hello from Rack!'.freeze]].freeze
|
17
|
-
|
18
|
-
hello = proc do |_env|
|
19
|
-
HELLO_RESPONSE
|
20
|
-
end
|
21
|
-
|
22
|
-
slow = proc do |env|
|
23
|
-
request = Rack::Request.new(env)
|
24
|
-
# Benchmark.bm do |bm|
|
25
|
-
# bm.report('Reading from env Hash to a string X 1000') { 1000.times { out = "ENV:\r\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n" } }
|
26
|
-
# bm.report('Creating the Rack::Request (can\'t repeat)') { 1.times { request = Rack::Request.new(env) } }
|
27
|
-
# end
|
28
|
-
if request.path_info == '/source'.freeze
|
29
|
-
[200, { 'X-Sendfile' => File.expand_path(__FILE__) }, []]
|
30
|
-
elsif request.path_info == '/file'.freeze
|
31
|
-
[200, { 'X-Header' => 'This was a Rack::Sendfile response' }, File.open(__FILE__)]
|
32
|
-
else
|
33
|
-
out = "ENV:\n<br/>\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n<br/>\n"}\n<br/>\n"
|
34
|
-
out += "\n<br/>\nRequest Path: #{request.path_info}\n<br/>\nParams:\n<br/>\n#{request.params.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n<br/>\n"}\n<br/>\n" unless request.params.empty?
|
35
|
-
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
36
|
-
'Content-Length'.freeze => out.length.to_s },
|
37
|
-
[out]]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
simple = proc do |env|
|
42
|
-
request = Rack::Request.new(env)
|
43
|
-
if request.path_info == '/source'.freeze
|
44
|
-
[200, { 'X-Sendfile' => File.expand_path(__FILE__) }, []]
|
45
|
-
elsif request.path_info == '/file'.freeze
|
46
|
-
[200, { 'X-Header' => 'This was a Rack::Sendfile response' }, File.open(__FILE__)]
|
47
|
-
else
|
48
|
-
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
49
|
-
'Content-Length'.freeze => request.path_info.length.to_s },
|
50
|
-
[request.path_info]]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
logo_png = nil
|
55
|
-
|
56
|
-
big = proc do |_env|
|
57
|
-
logo_png ||= IO.binread '../logo.png'
|
58
|
-
[200, { 'Content-Length'.freeze => logo_png.length.to_s , 'Content-Type'.freeze => 'image/png'.freeze}, [logo_png]]
|
59
|
-
end
|
60
|
-
|
61
|
-
bigX = proc do |_env|
|
62
|
-
logo_png ||= IO.binread '../logo.png'
|
63
|
-
[200, { 'Content-Length'.freeze => logo_png.length.to_s , 'Content-Type'.freeze => 'image/png'.freeze, 'X-Sendfile'.freeze => '../logo.png'.freeze}, [logo_png]]
|
64
|
-
end
|
65
|
-
|
66
|
-
case app
|
67
|
-
when 'simple'
|
68
|
-
use Rack::Sendfile
|
69
|
-
run simple
|
70
|
-
when 'hello'
|
71
|
-
run hello
|
72
|
-
when 'big'
|
73
|
-
run big
|
74
|
-
when 'bigX'
|
75
|
-
run bigX
|
76
|
-
when 'slow'
|
77
|
-
use Rack::Lint
|
78
|
-
run slow
|
79
|
-
else
|
80
|
-
run hello
|
81
|
-
end
|
82
|
-
|
83
|
-
# ab -n 1000000 -c 2000 -k http://127.0.0.1:3000/
|
84
|
-
# wrk -c400 -d5 -t12 http://localhost:3000/
|
85
|
-
#
|
86
|
-
# ab -n 1000000 -c 2000 -r http://127.0.0.1:3000/
|
87
|
-
# wrk -c400 -d5 -t12 -H"Connection: close" http://localhost:3000/
|
88
|
-
#
|
89
|
-
# def cycle
|
90
|
-
# puts `wrk -c4000 -d5 -t12 http://localhost:3000/`
|
91
|
-
# sleep(2)
|
92
|
-
# puts `wrk -c4000 -d5 -t12 http://localhost:3000/source`
|
93
|
-
# sleep(3)
|
94
|
-
# puts `wrk -c200 -d5 -t12 http://localhost:3000/file`
|
95
|
-
# true
|
96
|
-
# end
|
97
|
-
# sleep(10) while cycle
|
data/bin/echo
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# this will compile Iodine and run an echo server.
|
4
|
-
|
5
|
-
# # test using:
|
6
|
-
# telnet localhost 3000
|
7
|
-
|
8
|
-
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
9
|
-
puts `rake clean`
|
10
|
-
puts `rake compile`
|
11
|
-
|
12
|
-
require 'benchmark'
|
13
|
-
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
14
|
-
require 'bundler/setup'
|
15
|
-
require 'iodine'
|
16
|
-
|
17
|
-
class EchoProtocol
|
18
|
-
@timeout = 10
|
19
|
-
|
20
|
-
def self.on_start
|
21
|
-
puts '* Echo service is now running.'
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_open
|
25
|
-
puts 'New connection'
|
26
|
-
end
|
27
|
-
|
28
|
-
def ping
|
29
|
-
write "-- are you there?\n"
|
30
|
-
end
|
31
|
-
|
32
|
-
# `on_message` is an optional alternative to the `on_data` callback.
|
33
|
-
# `on_message` has a 1Kb buffer that recycles itself for memory optimization.
|
34
|
-
def on_message(buffer)
|
35
|
-
# writing will never block and will use a buffer written in C when needed.
|
36
|
-
write! "Echo: #{buffer}"
|
37
|
-
puts buffer.dump
|
38
|
-
close if buffer =~ /^bye[\r\n]/i
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# create the server object and setup any settings we might need.
|
43
|
-
Iodine.listen 3000, EchoProtocol
|
44
|
-
Iodine.threads = 10
|
45
|
-
# server.processes = 1
|
46
|
-
Iodine.start
|
data/bin/http-big
DELETED
@@ -1,63 +0,0 @@
|
|
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
|
-
# };
|