opal-up 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -51
  3. data/ext/up_ext/App.h +665 -544
  4. data/ext/up_ext/AsyncSocket.h +307 -284
  5. data/ext/up_ext/AsyncSocketData.h +35 -51
  6. data/ext/up_ext/BloomFilter.h +37 -42
  7. data/ext/up_ext/ChunkedEncoding.h +174 -175
  8. data/ext/up_ext/ClientApp.h +20 -23
  9. data/ext/up_ext/HttpContext.h +476 -381
  10. data/ext/up_ext/HttpContextData.h +20 -20
  11. data/ext/up_ext/HttpErrors.h +14 -10
  12. data/ext/up_ext/HttpParser.h +631 -563
  13. data/ext/up_ext/HttpResponse.h +526 -460
  14. data/ext/up_ext/HttpResponseData.h +59 -55
  15. data/ext/up_ext/HttpRouter.h +328 -310
  16. data/ext/up_ext/Loop.h +174 -168
  17. data/ext/up_ext/LoopData.h +60 -67
  18. data/ext/up_ext/MoveOnlyFunction.h +71 -80
  19. data/ext/up_ext/PerMessageDeflate.h +218 -198
  20. data/ext/up_ext/ProxyParser.h +100 -99
  21. data/ext/up_ext/QueryParser.h +91 -84
  22. data/ext/up_ext/TopicTree.h +273 -268
  23. data/ext/up_ext/Utilities.h +25 -25
  24. data/ext/up_ext/WebSocket.h +376 -310
  25. data/ext/up_ext/WebSocketContext.h +487 -372
  26. data/ext/up_ext/WebSocketContextData.h +74 -62
  27. data/ext/up_ext/WebSocketData.h +53 -46
  28. data/ext/up_ext/WebSocketExtensions.h +194 -178
  29. data/ext/up_ext/WebSocketHandshake.h +115 -110
  30. data/ext/up_ext/WebSocketProtocol.h +441 -398
  31. data/ext/up_ext/extconf.rb +1 -1
  32. data/ext/up_ext/libuwebsockets.cpp +1262 -1292
  33. data/ext/up_ext/libuwebsockets.h +337 -201
  34. data/ext/up_ext/up_ext.c +853 -163
  35. data/lib/up/bun/rack_env.rb +1 -13
  36. data/lib/up/bun/server.rb +93 -19
  37. data/lib/up/cli.rb +3 -0
  38. data/lib/up/client.rb +68 -0
  39. data/lib/up/ruby/cluster.rb +62 -0
  40. data/lib/up/ruby/rack_cluster.rb +1 -1
  41. data/lib/up/ruby/rack_server.rb +0 -1
  42. data/lib/up/u_web_socket/cluster.rb +18 -3
  43. data/lib/up/u_web_socket/server.rb +108 -15
  44. data/lib/up/version.rb +1 -1
  45. metadata +4 -15
  46. data/bin/up_node +0 -12
  47. data/bin/up_node_cluster +0 -12
  48. data/lib/up/node/cluster.rb +0 -39
  49. data/lib/up/node/cluster_cli.rb +0 -15
  50. data/lib/up/node/rack_cluster.rb +0 -25
  51. data/lib/up/node/rack_env.rb +0 -106
  52. data/lib/up/node/rack_server.rb +0 -25
  53. data/lib/up/node/server.rb +0 -84
  54. data/lib/up/node/server_cli.rb +0 -15
  55. data/lib/up/ruby/rack_env.rb +0 -97
  56. data/lib/up/u_web_socket/rack_env.rb +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92cb787ff140257bb7f11eecfb460e9c9d458be90e723187e6c4ac9006ce1f22
4
- data.tar.gz: 5d5046c915394b4c649bee550df9b25a604707655e6746e8487a0c198c26dd0a
3
+ metadata.gz: cd09c3697caf76eb487770a2818af0a06ee4711761a15f2d80d7d0d291747234
4
+ data.tar.gz: cc53773debbd42d66a2aa99e1b3d9ec3e3fcd05db99f5e58bfab94e5ecf1811a
5
5
  SHA512:
6
- metadata.gz: be462aea9b579379ee5234dba708bc37ce92705bb3783d2bdcfbce367fc12a0fc606448ee868f7ef1322d65d252e036368a722ddcf9e5a12996511d49f5059d2
7
- data.tar.gz: 1baf0f1da6697e95aaea33049b81bc45a0e136a1a79810284df99e7dfa5de58fdf3980fa25ccb74f29a184300f7bafd8c4ef193e1de6173741630c5c2b4ef68a
6
+ metadata.gz: 38c374376cfe497c4abd8039272ae616d44e5152d3ba15fc47578d789bd16d88cf8af21d2471fd71eafa0e3852f60704a0aabf03dd560bac2de5c87591724d1a
7
+ data.tar.gz: 0467d90a76aedd75515f38c678ce7cdcac7e36760a687c9ae6283dfdd9723ea2d0e005d67e357fbcf60491c594511c45be105002a008f650c2eb488f5f315c53
data/README.md CHANGED
@@ -3,68 +3,58 @@
3
3
 
4
4
  # UP!
5
5
 
6
- A high performance Rack server for [Opal Ruby](https://github.com/opal/opal), Tech Demo
6
+ A high performance Rack server for [Opal Ruby](https://opalrb.com/) and [Matz Ruby](https://www.ruby-lang.org/), Tech Demo
7
7
 
8
8
  ## Let Numbers speak first
9
9
 
10
10
  ```
11
- Response type: env.to_s "hello_world"
12
- Requests/Second:
13
- Puma: 9478.41 req/s 50822.38 req/s
14
- Unicorn: 12267.86 req/s 16329.68 req/s
15
- Falcon: 13569.35 req/s 24041.63 req/s
16
- Racer: 14640.34 req/s 15354.14 req/s
17
- Agoo: 51455.38 req/s 89022.91 req/s
18
- Iodine: 57257.21 req/s <<< 132723.02 req/s
19
- Up! node: 2096.64 req/s* 25041.14 req/s
20
- Up! ruby: 10616.74 req/s 69388.90 req/s
21
- Up! uWS: 2511.65 req/s* 83853.44 req/s
22
- Up! node cluster: 6627.05 req/s* 61320.38 req/s
23
- Up! ruby cluster: 29807.97 req/s 137782.65 req/s
24
- Up! uWS cluster: 8328.87 req/s* 152865.96 req/s <<< fastest
25
-
26
- Latency:
27
- Puma: 14.05 ms 2.62 ms
28
- Unicorn: 10.26 ms 7.68 ms
29
- Falcon: 9.32 ms 5.26 ms
30
- Racer: 8.90 ms 8.44 ms
31
- Agoo: 2.43 ms 1.51 ms
32
- Iodine: 2.18 ms <<< 0.94 ms
33
- Up! node: 59.97 ms* 4.99 ms
34
- Up! uWS: 49.83 ms* 1.49 ms
35
- Up! ruby: 11.76 ms 1.80 ms
36
- Up! node cluster: 18.83 ms* 2.04 ms
37
- Up! ruby cluster: 4.19 ms 0.91 ms
38
- Up! uWS cluster: 14.99 ms* 0.82 ms <<< fastest
11
+ Response type: env.to_s "hello_world"
12
+ Requests/Second Latency Requests/Second Latency
13
+ Puma: 8884.53 req/s 15.18 ms 50822.38 req/s 2.62 ms
14
+ Unicorn: 12302.35 req/s 10.22 ms 16329.68 req/s 7.68 ms
15
+ Falcon: 13168.82 req/s 9.49 ms 24041.63 req/s 5.26 ms
16
+ Racer: 14536.88 req/s 8.94 ms 15354.14 req/s 8.44 ms
17
+ Agoo: 49078.57 req/s 2.54 ms 89022.91 req/s 1.51 ms
18
+ Iodine: 59116.53 req/s 2.11 ms <<< 134267.79 req/s 0.93 ms
19
+ Up! bun: 3900.44 req/s 32.00 ms 47334.16 req/s 2.64 ms
20
+ Up! ruby: 22144.33 req/s 5.64 ms 58704.09 req/s 2.14 ms
21
+ Up! uWS: 6540.62 req/s 19.09 ms 78384.93 req/s 1.59 ms
22
+ Up! ruby cluster: 53641.29 req/s 2.35 ms 128237.52 req/s 0.97 ms
23
+ Up! uWS cluster: 20143.62 req/s 6.20 ms 152353.97 req/s 0.82 ms <<<
24
+
25
+ <<< denotes the fastest for the response type
39
26
 
40
27
  running on/with:
41
28
  Linux, Kernel 6.5.0-x
42
29
  ruby 3.3.0, YJit enabled
43
- Opal 2.0-dev with node v20.11.0
30
+ Opal 2.0-dev as of 9. Feb 2024, with node v20.11.0
44
31
  Puma 6.4.2, 4 workers, 4 threads
45
32
  Falcon 0.43.0, 4 workers, 4 threads
46
33
  Racer 0.1.3, defaults
47
34
  Unicorn 6.1.0, 4 workers
48
35
  Agoo 2.15.8, 4 workers, 4 threads
49
36
  Iodine 0.7.57, 4 workers, 1 thread
50
- Up! uWS 0.0.2, 1 worker
51
- Up! Node 0.0.2, 1 worker
52
- Up! Ruby 0.0.3, 1 worker
53
- Up! uWS cluster 0.0.2, 4 workers
54
- Up! Node cluster 0.0.2, 4 workers
55
- Up! Ruby cluster 0.0.3, 4 workers
37
+ Up! uWS 0.0.4, 1 worker
38
+ Up! Node 0.0.4, 1 worker
39
+ Up! Ruby 0.0.4, 1 worker
40
+ Up! uWS cluster 0.0.4, 4 workers
41
+ Up! Node cluster 0.0.4, 4 workers
42
+ Up! Ruby cluster 0.0.4, 4 workers
56
43
 
57
44
  running the example_rack_app from this repo, benchmarked with:
58
45
  bombardier http://localhost:3000/
46
+ and taking the Avg
59
47
 
60
- on my old Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
61
-
62
- * please see section "About the benchmarks ..." below
48
+ on a Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
63
49
  ```
64
50
 
65
51
  ## Introduction
66
52
 
67
- This is currently mainly a technical demonstration, demonstrating the speed of the [Opal Ruby](https://github.com/opal/opal) implementation employing [Node](https://nodejs.org/en) and [uWebSocketJs](https://github.com/uNetworking/uWebSockets.js) as runtime. Its not yet a generic, all purpose Rack server, but good for further experimentation, research and open for improvement.
53
+ This is currently mainly a technical demonstration, demonstrating the speed of the [Opal Ruby](https://github.com/opal/opal) implementation employing [Node](https://nodejs.org/en) and [uWebSocketJs](https://github.com/uNetworking/uWebSockets.js) as runtime.
54
+
55
+ Its not yet a generic, all purpose Rack server, but good for further experimentation, research and open for improvement. The included ruby version allows for verification of code correctness and performance. If it works with `bundle exec up_ruby` it should work equally well with the various Opal versions, at least thats the future goal.
56
+
57
+ Its a intention of this project, to serve as a tool for enhancing Opal Ruby and porting Rack apps from Matz to Opal Ruby.
68
58
 
69
59
  ## Getting started
70
60
 
@@ -82,15 +72,13 @@ For a Gemfile available from rubygems:
82
72
 
83
73
  ## Available Commands
84
74
 
85
- Available with `bundle exec` within the example apps or if this gem is included in your Gemfile:
75
+ Available with `bundle exec` within the example apps or if this gem is included in your Gemfile:
86
76
 
87
- - `up` - starts a single worker server using Opal with uWebSockets, fastest server
88
- - `up_cluster` - starts a cluster of workers using Opal with uWebSockets, still fast, depending on workload may be even faster than the single worker or not
89
- - `up_node` - starts a single worker server using Opal with the standard Node HTTP(S) classes
90
- - `up_node_cluster` - starts a cluster of workers using Opal with the standard Node HTTP(S) classes, probably faster than `up_node`
77
+ - `up` - starts a single worker server using Opal with uWebSockets
78
+ - `up_cluster` - starts a cluster of workers using Opal with uWebSockets, fastest server
91
79
  - `up_bun` - starts single worker server using Bun, requires Opal bun support from [PR#2622](https://github.com/opal/opal/pull/2622)
92
- - `up_ruby` - starts a single worker using Ruby with uWebSockets in a native extension
93
- - `up_ruby_cluster` - starts a cluster of workers using Ruby with uWebSockets in a native extension
80
+ - `up_ruby` - starts a single worker using Ruby with uWebSockets in a native extension, does not support the --secure option/TLS
81
+ - `up_ruby_cluster` - starts a cluster of workers using Ruby with uWebSockets in a native extension, does not support the --secure options/TLS
94
82
 
95
83
  ```
96
84
  Usage: up [options]
@@ -106,13 +94,25 @@ When using secure sockets, the -a, -c and -k options must be provided
106
94
  -v, --version Show version
107
95
 
108
96
  ```
97
+ ## Supported Features
98
+
99
+ Up! implements the [Rack Spec as of Rack 3.0](https://github.com/rack/rack/blob/main/SPEC.rdoc) with the following differences:
100
+ - `rack.hijack` is not implemented, but `rack.upgrade` instead is, see "Websockets" below
101
+ - `rack.input` is currently still missing
102
+ - Tempfile support is currently incomplete, affecting a few keys in the Rack Env ('tempfile' missing in Opal).
103
+ - Some Rack modules/classes still have issues when run in Opal and may not work as expected
104
+
105
+ Websockets are supported following the [Iodine SPEC-WebSocket-Draft](https://github.com/boazsegev/iodine/blob/master/SPEC-WebSocket-Draft.md).
106
+ PubSub is supported following the [Iodine SPEC-PubSub-Draft](https://github.com/boazsegev/iodine/blob/master/SPEC-PubSub-Draft.md), except for engines.
107
+
108
+ A example RackApp using WebSockets and PubSub is provided in the 'example_rack_ws_app' directory
109
109
 
110
110
  ## Roda
111
111
 
112
112
  A example app for Roda is provided and _appears_ working with the following patches applied:
113
113
 
114
114
  - [Changes required to make Roda _appear_ to work](https://github.com/jeremyevans/roda/compare/master...janbiedermann:roda:master)
115
- - [Changes required to make Rack _appear_ to work](https://github.com/janbiedermann/rack/commit/1dadea0f9813c2df94715052d2277af13f7d0c0c)
115
+ - [Changes required to make Rack with Roda _appear_ to work](https://github.com/janbiedermann/rack/commit/1dadea0f9813c2df94715052d2277af13f7d0c0c)
116
116
 
117
117
  Please note the phrase "_appear_ to work" in above sentences.
118
118
  To try:
@@ -129,8 +129,23 @@ To try:
129
129
  - [Mustermann patches](https://github.com/sinatra/mustermann/compare/main...janbiedermann:mustermann:main)
130
130
  - [Rack-Session patches](https://github.com/rack/rack-session/compare/main...janbiedermann:rack-session:main)
131
131
 
132
- ## About the benchmarks and Opal/Up! performance
132
+ ## About the Benchmarks
133
+
134
+ The benchmarks mainly test the overhead introduced by the rack server.
135
+
136
+ In the 'env.to_s' benchmark, the Rack environment access and response header handling overhead are measured. Simply calling env.to_s accesses all keys and serializes them briefly. If the Rack app accesses the keys of the Rack environment and sets response headers, the overhead/latency as measured can be expected, or that amount of requests per second can be expected at most.
137
+
138
+ The "hello_world" benchmark measures the overhead for the simplest possible version of a meaningful Rack response and should provide maximum performance. If the Rack app just replies with a string, that overhead/latency can be expected, or that amount of requests per second can be expected at most.
139
+
140
+ ## Links
141
+
142
+ - bombardier, the tool used for benchmarking: [https://github.com/codesenberg/bombardier](https://github.com/codesenberg/bombardier)
133
143
 
134
- The "hello world" benchmark results above demonstrates the great potential of using Opal/Node with uWebSocketsJs on the server for executing ruby, however, the `envt.to_s` benchmark column next to it (results marked with *) also shows, that its still possible to trigger sweet spots in Opal, that can make things a bit slow. Work continues to improve things.
144
+ ### Rack Servers
135
145
 
136
- Link to bombardier, the tool used for benchmarking: [https://github.com/codesenberg/bombardier](https://github.com/codesenberg/bombardier)
146
+ - [Agoo](https://github.com/ohler55/agoo)
147
+ - [Falcon](https://github.com/socketry/falcon)
148
+ - [Iodine](https://github.com/boazsegev/iodine)
149
+ - [Puma](https://github.com/puma/puma)
150
+ - [Racer](https://rubygems.org/gems/racer) (a bit old, but included here, because it uses libuv, just like Node)
151
+ - [Unicorn](https://yhbt.net/unicorn/)