opal-up 0.0.10 → 0.0.12

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: 9f982def506c46ff2a3e6ebc643bb2912328c41f2ea567ed90798ae9aba5d77c
4
- data.tar.gz: 94dc8ee059b890fb29202e5dd385d453bf55ae5ce2ff1e204d51ef4237b2c8f3
3
+ metadata.gz: e93a1ac4cfc5ff09d0e1d6d61fbb4d5e9d1c3798df8dcadba8925b8050e95bf5
4
+ data.tar.gz: 40dffea08fef4cebb727334402bc6047f233a0cba6545a49cf9de8d6237b85aa
5
5
  SHA512:
6
- metadata.gz: 1fa8b59299863062afc1ba8198cb5cded331376fa888792b5e18c214eac53dddf64bec068442d32da887835706f88127dde6a6b928674307fe5bdcdcc49aa6e4
7
- data.tar.gz: de2c81dbffc628235523e6dfb812bafabfedf499a57782261340598de05b34304a05cff850b7b221197d0d4468715731e486b86c54878c54a595b59f506552fb
6
+ metadata.gz: 18cddc9768c2659ed8f3396d76d8b7d13eca3f4c4181b8e80b2baab04c2bb0630e0aa0b7a9dc2dc79d345288036eb1e5c715fb252bea0c93de6daf584eafb808
7
+ data.tar.gz: fd4a765163a1255f6f905f7bc42af1f8412e37998e079282cfc6f3bdc480ecb07bdff58d0d04354d9a6d79f93c5a207e65c09e246a60e781a8c551440860d9b9
data/README.md CHANGED
@@ -17,8 +17,6 @@ Racer: 14536.88 req/s 8.94 ms 15354.14 req/s 8.44 ms
17
17
  Agoo: 49078.57 req/s 2.54 ms 89022.91 req/s 1.51 ms
18
18
  Iodine: 59116.53 req/s 2.11 ms <<< 134267.79 req/s 0.93 ms
19
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
20
  Up! ruby cluster: 53641.29 req/s 2.35 ms 128237.52 req/s 0.97 ms
23
21
  Up! uWS cluster: 20143.62 req/s 6.20 ms 152353.97 req/s 0.82 ms <<<
24
22
 
@@ -34,11 +32,8 @@ Racer 0.1.3, defaults
34
32
  Unicorn 6.1.0, 4 workers
35
33
  Agoo 2.15.8, 4 workers, 4 threads
36
34
  Iodine 0.7.57, 4 workers, 1 thread
37
- Up! uWS 0.0.4, 1 worker
38
- Up! Node 0.0.4, 1 worker
39
- Up! Ruby 0.0.4, 1 worker
35
+ Up! bun 0.0.4, 1 worker
40
36
  Up! uWS cluster 0.0.4, 4 workers
41
- Up! Node cluster 0.0.4, 4 workers
42
37
  Up! Ruby cluster 0.0.4, 4 workers
43
38
 
44
39
  running the example_rack_app from this repo, benchmarked with:
@@ -74,11 +69,9 @@ For a Gemfile available from rubygems:
74
69
 
75
70
  Available with `bundle exec` within the example apps or if this gem is included in your Gemfile:
76
71
 
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
72
+ - `up` - starts a cluster of workers using Opal with uWebSockets, fastest server
79
73
  - `up_bun` - starts single worker server using Bun, requires Opal bun support from [PR#2622](https://github.com/opal/opal/pull/2622)
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
74
+ - `up_ruby` - starts a cluster of workers using Ruby with uWebSockets in a native extension, does not support the --secure options/TLS
82
75
 
83
76
  ```
84
77
  Usage: up [options]
@@ -92,6 +85,7 @@ When using secure sockets, the -a, -c and -k options must be provided
92
85
  -c, --cert-file FILE File with the servers certificate
93
86
  -k, --key-file FILE File with the servers certificate
94
87
  -l, --log-file FILE Log file
88
+ -p, --pid-file FILE PID file
95
89
  -v, --version Show version
96
90
  -w, --workers NUMBER For clusters, the number of workers to run. Default: number of processors
97
91
  ```
data/bin/up CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  if RUBY_ENGINE == 'opal'
4
- require 'up/u_web_socket/server_cli'
4
+ require 'up/u_web_socket/cluster_cli'
5
5
  Up::CLI.call
6
6
  else
7
7
  require 'up/cli'
data/bin/up_ruby CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'up/cli'
3
- require 'up/ruby/server_cli'
3
+ require 'up/ruby/cluster_cli'
4
4
  Up::CLI.call
data/ext/up_ext/up_ext.c CHANGED
@@ -1,6 +1,7 @@
1
1
  #include "libusockets.h"
2
2
  #include "libuwebsockets.h"
3
3
  #include <arpa/inet.h>
4
+ #include <netinet/in.h>
4
5
  #include <ruby.h>
5
6
  #include <ruby/encoding.h>
6
7
  #include <signal.h>
@@ -13,6 +14,12 @@
13
14
  #define MAX_HEADER_KEY_LEN 255
14
15
  #define INTERNAL_PUBLISH_PATH "/__up__cluster__publish__"
15
16
 
17
+ #undef close
18
+
19
+ #ifndef MSG_MORE
20
+ #define MSG_MORE 0
21
+ #endif
22
+
16
23
  static VALUE mUp;
17
24
  static VALUE mRuby;
18
25
  static VALUE cServer;
@@ -126,8 +133,8 @@ typedef struct server_s {
126
133
  VALUE env_template;
127
134
  VALUE body;
128
135
  VALUE env;
129
- int workers;
130
- int member_id;
136
+ long workers;
137
+ long member_id;
131
138
  char secret[37];
132
139
  } server_s;
133
140
 
@@ -210,9 +217,9 @@ static int up_internal_res_header_handler(VALUE key, VALUE data, VALUE arg) {
210
217
  return ST_CONTINUE;
211
218
  }
212
219
  char *key_s = RSTRING_PTR(key);
213
- int key_len = RSTRING_LEN(key);
220
+ long key_len = RSTRING_LEN(key);
214
221
  char *data_s = RSTRING_PTR(data);
215
- int data_len = RSTRING_LEN(data);
222
+ long data_len = RSTRING_LEN(data);
216
223
 
217
224
  if (key_len > MAX_HEADER_KEY_LEN)
218
225
  key_len = MAX_HEADER_KEY_LEN;
@@ -479,8 +486,7 @@ static void up_client_cluster_publish(char *scrt, int st, VALUE channel,
479
486
  MSG_DONTROUTE | MSG_MORE);
480
487
  send(st, boundary_disposition, strlen(boundary_disposition),
481
488
  MSG_DONTROUTE | MSG_MORE);
482
- send(st, RSTRING_PTR(message), RSTRING_LEN(message),
483
- MSG_DONTROUTE | MSG_MORE);
489
+ send(st, RSTRING_PTR(message), RSTRING_LEN(message), MSG_DONTROUTE);
484
490
 
485
491
  // char read_buf[256];
486
492
  // if (read(st, read_buf, 256)) {
@@ -490,7 +496,7 @@ static void up_client_cluster_publish(char *scrt, int st, VALUE channel,
490
496
  }
491
497
 
492
498
  static void up_internal_publish_to_member(server_s *s, VALUE channel,
493
- VALUE message, int member_idx) {
499
+ VALUE message, long member_idx) {
494
500
  struct sockaddr_in member_addr = {.sin_addr.s_addr = inet_addr("127.0.0.1"),
495
501
  .sin_family = AF_INET};
496
502
  int st = socket(AF_INET, SOCK_STREAM, 0);
@@ -521,7 +527,7 @@ static VALUE up_client_publish(VALUE self, VALUE channel, VALUE message) {
521
527
  if (s->member_id > 0) {
522
528
 
523
529
  // publish to cluster members
524
- int i;
530
+ long i;
525
531
  for (i = 1; i <= s->workers; i++) {
526
532
  if (i != s->member_id)
527
533
  up_internal_publish_to_member(s, channel, message, i);
@@ -672,7 +678,7 @@ static void up_ws_close_handler(uws_websocket_t *ws, int code,
672
678
  VALUE rhandler = rb_ivar_get(*client, at_handler);
673
679
  if (rb_respond_to(rhandler, id_on_close))
674
680
  rb_funcall(rhandler, id_on_close, 1, *client);
675
- // rb_gc_unregister_address(client);
681
+ rb_gc_unregister_address(client);
676
682
  DATA_PTR(*client) = NULL;
677
683
  free(client);
678
684
  }
@@ -729,7 +735,7 @@ static void up_ws_upgrade_handler(uws_res_t *res, uws_req_t *req,
729
735
  // upgrade
730
736
 
731
737
  VALUE *client = malloc(sizeof(VALUE));
732
- // rb_gc_register_address(client);
738
+ rb_gc_register_address(client);
733
739
  *client = rb_class_new_instance(0, NULL, cClient);
734
740
  rb_ivar_set(*client, at_env, renv);
735
741
  rb_ivar_set(*client, at_open, false);
@@ -836,8 +842,10 @@ static VALUE up_server_listen(VALUE self) {
836
842
  s->secret[36] = '\0';
837
843
  uws_app_any(USE_SSL, s->app, INTERNAL_PUBLISH_PATH,
838
844
  up_internal_publish_handler, (void *)s);
839
- uws_app_listen_config_t config_internal = {
840
- .port = config.port + s->member_id, .host = "localhost", .options = 0};
845
+ uws_app_listen_config_t config_internal = {.port = config.port +
846
+ (int)s->member_id,
847
+ .host = "localhost",
848
+ .options = 0};
841
849
  uws_app_listen_with_config(false, s->app, config_internal,
842
850
  up_server_cluster_listen_handler, NULL);
843
851
  } else {
@@ -885,7 +893,7 @@ static VALUE up_server_publish(VALUE self, VALUE channel, VALUE message) {
885
893
  RSTRING_PTR(message), RSTRING_LEN(message), TEXT, false);
886
894
  if (s->member_id > 0) {
887
895
  // publish to cluster members
888
- int i;
896
+ long i;
889
897
  for (i = 1; i <= s->workers; i++) {
890
898
  if (i != s->member_id)
891
899
  up_internal_publish_to_member(s, channel, message, i);
data/lib/up/bun/server.rb CHANGED
@@ -14,7 +14,10 @@ module Up
14
14
 
15
15
  module Bun
16
16
  class Server
17
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
17
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http',
18
+ ca_file: nil, cert_file: nil, key_file: nil,
19
+ pid_file: nil,
20
+ logger: Logger.new(STDERR))
18
21
  @app = app
19
22
  @scheme = scheme || 'http'
20
23
  raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
@@ -24,6 +27,7 @@ module Up
24
27
  @ca_file = ca_file
25
28
  @cert_file = cert_file
26
29
  @key_file = key_file
30
+ @pid_file = pid_file
27
31
  @default_input = StringIO.new('', 'r')
28
32
  @server = nil
29
33
  @logger = logger
@@ -54,9 +58,12 @@ module Up
54
58
  return body;
55
59
  }
56
60
  }
61
+
57
62
  def listen
58
63
  raise "already running" if @server
59
64
  ::Up.instance_variable_set(:@instance, self)
65
+ File.write(@pid_file, `process.pid.toString()`) if @pid_file
66
+ puts "Server PID: #{`process.pid`}"
60
67
  %x{
61
68
  const oubs = Opal.Up.Bun.Server;
62
69
  const ouwc = Opal.Up.Client;
data/lib/up/cli.rb CHANGED
@@ -35,6 +35,9 @@ module Up
35
35
  on('-l', '--log-file FILE', String, 'Log file') do |log_file|
36
36
  options[:logger] = Logger.new(File.new(log_file, 'a+'))
37
37
  end
38
+ on('-p', '--pid-file FILE', String, 'PID file') do |pid_file|
39
+ options[:pid_file] = pid_file
40
+ end
38
41
  on('-v', '--version', 'Show version') do
39
42
  puts "Up! v#{Up::VERSION}"
40
43
  exit
@@ -7,8 +7,12 @@ require 'up_ext'
7
7
  module Up
8
8
  module Ruby
9
9
  class Cluster < Up::Ruby::Server
10
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR), workers: nil)
10
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http',
11
+ ca_file: nil, cert_file: nil, key_file: nil,
12
+ pid_file: nil,
13
+ logger: Logger.new(STDERR), workers: nil)
11
14
  super(app: app, host: host, port: port)
15
+ @pid_file = pid_file
12
16
  @secret = Random.uuid
13
17
  @workers = workers || Etc.nprocessors
14
18
  @members = []
@@ -24,6 +28,8 @@ module Up
24
28
  super
25
29
  end
26
30
  end
31
+ File.write(@pid_file, Process.pid.to_s) if @pid_file
32
+ puts "Server PID: #{Process.pid}"
27
33
  unless @member_id
28
34
  install_signal_handlers
29
35
  Process.waitall
@@ -33,6 +39,7 @@ module Up
33
39
  def stop
34
40
  if Up::CLI::stoppable?
35
41
  kill_members
42
+ super
36
43
  end
37
44
  end
38
45
 
@@ -49,6 +56,10 @@ module Up
49
56
  warn "\nReceived CTRL-C!"
50
57
  kill_members
51
58
  end
59
+ Signal.trap('TERM') do
60
+ warn "\nReceived TERM signal!"
61
+ kill_members
62
+ end
52
63
  end
53
64
 
54
65
  def kill_members
@@ -4,15 +4,20 @@ require 'up/u_web_socket/server'
4
4
  %x{
5
5
  const process = require('node:process');
6
6
  const cluster = require('node:cluster');
7
+ const filesys = require('node:fs') ;
7
8
  const num_workers = require('node:os').availableParallelism();
8
9
  }
9
10
 
10
11
  module Up
11
12
  module UWebSocket
12
13
  class Cluster < Up::UWebSocket::Server
13
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR), workers: nil)
14
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http',
15
+ ca_file: nil, cert_file: nil, key_file: nil,
16
+ pid_file: nil,
17
+ logger: Logger.new(STDERR), workers: nil)
14
18
  super(app: app, host: host, port: port, scheme: scheme, ca_file: ca_file, cert_file: cert_file, key_file: key_file, logger: logger)
15
19
  @workers = workers || `num_workers`
20
+ @pid_file = pid_file
16
21
  @members = []
17
22
  end
18
23
 
@@ -21,6 +26,10 @@ module Up
21
26
  ::Up.instance_variable_set(:@instance, self)
22
27
  %x{
23
28
  if (cluster.isPrimary) {
29
+ #{
30
+ File.write(@pid_file, `process.pid.toString()`) if @pid_file
31
+ puts "Server PID: #{`process.pid`}"
32
+ }
24
33
  cluster.on('message', (worker, message, handle) => {
25
34
  if (message.c && message.m) {
26
35
  for (let member of #@members) {
@@ -1,4 +1,5 @@
1
1
  require 'opal/platform'
2
+ require 'nodejs'
2
3
  require 'nodejs/file'
3
4
  require 'nodejs/require'
4
5
  require 'opal-parser'
@@ -74,7 +74,7 @@ module Up
74
74
  env.set('PATH_INFO', req.getUrl());
75
75
  req.forEach((k, v) => {
76
76
  let h = k.toUpperCase().replaceAll('-', '_');
77
- if (h[0] === 'C' && (h === 'CONTENT_TYPE || h === 'CONTENT_LENGTH')) {
77
+ if (h[0] === 'C' && (h === 'CONTENT_TYPE' || h === 'CONTENT_LENGTH')) {
78
78
  env.set(h, v) ;
79
79
  } else {
80
80
  env.set('HTTP_' + h, v) ;
data/lib/up/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Up
2
- VERSION = '0.0.10'.freeze
2
+ VERSION = '0.0.12'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-up
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-18 00:00:00.000000000 Z
11
+ date: 2024-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -106,9 +106,7 @@ email:
106
106
  executables:
107
107
  - up
108
108
  - up_bun
109
- - up_cluster
110
109
  - up_ruby
111
- - up_ruby_cluster
112
110
  extensions:
113
111
  - ext/up_ext/extconf.rb
114
112
  extra_rdoc_files: []
@@ -117,9 +115,7 @@ files:
117
115
  - README.md
118
116
  - bin/up
119
117
  - bin/up_bun
120
- - bin/up_cluster
121
118
  - bin/up_ruby
122
- - bin/up_ruby_cluster
123
119
  - ext/up_ext/App.h
124
120
  - ext/up_ext/AsyncSocket.h
125
121
  - ext/up_ext/AsyncSocketData.h
@@ -171,14 +167,10 @@ files:
171
167
  - lib/up/ruby/cluster.rb
172
168
  - lib/up/ruby/cluster_cli.rb
173
169
  - lib/up/ruby/rack_cluster.rb
174
- - lib/up/ruby/rack_server.rb
175
- - lib/up/ruby/server_cli.rb
176
170
  - lib/up/u_web_socket/cluster.rb
177
171
  - lib/up/u_web_socket/cluster_cli.rb
178
172
  - lib/up/u_web_socket/rack_cluster.rb
179
- - lib/up/u_web_socket/rack_server.rb
180
173
  - lib/up/u_web_socket/server.rb
181
- - lib/up/u_web_socket/server_cli.rb
182
174
  - lib/up/version.rb
183
175
  homepage: https://github.com/janbiedermann/up
184
176
  licenses:
data/bin/up_cluster DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- if RUBY_ENGINE == 'opal'
4
- require 'up/u_web_socket/cluster_cli'
5
- Up::CLI.call
6
- else
7
- require 'up/cli'
8
- Up::CLI.setup_u_web_socket
9
- lib_dir = File.expand_path("#{__dir__}/../lib")
10
- gems = Up::CLI.get_gems_for_cmd
11
- Kernel.exec("opal -Rnodejs -E -I. -I#{lib_dir} -g rack #{gems} #{__FILE__} -- #{ARGV.join(' ')}")
12
- end
data/bin/up_ruby_cluster DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'up/cli'
3
- require 'up/ruby/cluster_cli'
4
- Up::CLI.call
@@ -1,25 +0,0 @@
1
- require 'up_ext'
2
-
3
- module Up
4
- module Ruby
5
- module RackServer
6
- def self.run(app, options = {})
7
- raise "already running" if @server
8
- @server = Up::Ruby::Server.new(app: app, **options).listen
9
- true
10
- end
11
-
12
- def self.shutdown
13
- @server&.stop
14
- @server = nil
15
- end
16
- end
17
- end
18
- end
19
-
20
- ENV['RACK_HANDLER'] ||= 'up'
21
-
22
- begin
23
- ::Rackup::Handler.register('up', Up::Ruby::RackServer) if defined?(::Rackup::Handler)
24
- rescue StandardError
25
- end
@@ -1,10 +0,0 @@
1
- require 'rack/builder'
2
- require 'up/ruby/rack_server'
3
-
4
- module Up
5
- module CLI
6
- def self.call
7
- Up::Ruby::RackServer.run(get_app, get_options)
8
- end
9
- end
10
- end
@@ -1,25 +0,0 @@
1
- require 'up/u_web_socket/server'
2
-
3
- module Up
4
- module UWebSocket
5
- module RackServer
6
- def self.run(app, options = {})
7
- raise "already running" if @server
8
- @server = Up::UWebSocket::Server.new(app: app, **options).listen
9
- true
10
- end
11
-
12
- def self.shutdown
13
- @server&.stop
14
- @server = nil
15
- end
16
- end
17
- end
18
- end
19
-
20
- ENV['RACK_HANDLER'] ||= 'up'
21
-
22
- begin
23
- ::Rackup::Handler.register('up', Up::UWebSocket::RackServer) if defined?(::Rackup::Handler)
24
- rescue StandardError
25
- end
@@ -1,15 +0,0 @@
1
- require 'opal/platform'
2
- require 'nodejs/file'
3
- require 'nodejs/require'
4
- require 'opal-parser'
5
- require 'rack/builder'
6
- require 'up/rack_builder_patch'
7
- require 'up/u_web_socket/rack_server'
8
-
9
- module Up
10
- module CLI
11
- def self.call
12
- Up::UWebSocket::RackServer.run(get_app, get_options)
13
- end
14
- end
15
- end