opal-up 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,26 +23,14 @@ module Up
23
23
  self[key] = case key
24
24
  when 'rack.errors'
25
25
  STDERR
26
- when 'rack.hijack'
27
- nil
28
- when 'rack.hijack?'
29
- false
30
- when 'rack.input'
31
- ::IO.new
32
26
  when 'rack.logger'
33
- ::Logger.new(self['rack.errors'])
27
+ @config[:logger]
34
28
  when 'rack.multipart.buffer_size'
35
29
  4096
36
30
  when 'rack.multipart.tempfile_factory'
37
31
  proc { |_filename, _content_type| File.new }
38
- when 'rack.response_finished'
39
- []
40
32
  when 'rack.session'
41
33
  {}
42
- when 'rack.upgrade'
43
- nil
44
- when 'rack.upgrade?'
45
- nil
46
34
  when 'rack.url_scheme'
47
35
  @config[:scheme]
48
36
  when 'PATH_INFO'
data/lib/up/bun/server.rb CHANGED
@@ -1,36 +1,37 @@
1
1
  # backtick_javascript: true
2
+ require 'logger'
2
3
  require 'up/cli'
3
- require 'up/bun/rack_env'
4
+ require 'up/client'
4
5
 
5
6
  module Up
6
7
  module Bun
7
8
  class Server
8
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil)
9
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
9
10
  @app = app
10
11
  @scheme = scheme || 'http'
11
12
  raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
12
13
  @host = host || 'localhost'
13
14
  @port = port&.to_i || 3000
14
- @config = { handler: self.class.name, engine: "bun/#{`process.version`}", port: port, scheme: scheme, host: host }.freeze
15
+ @config = { handler: self.class.name, engine: "bun/#{`process.version`}", port: port, scheme: scheme, host: host, logger: logger }.freeze
15
16
  @ca_file = ca_file
16
17
  @cert_file = cert_file
17
18
  @key_file = key_file
18
- @server = nil
19
+ @default_input = IO.new
20
+ @server = nil
21
+ @logger = logger
22
+ @t_factory = proc { |filename, _content_type| File.new(filename, 'a+') }
19
23
  end
20
24
 
21
25
  %x{
22
26
  self.handle_headers = function(rack_headers, bun_hdr) {
23
27
  if (rack_headers.$$is_hash) {
24
- var header, k, v;
28
+ var header, v;
25
29
  for(header of rack_headers) {
26
- k = header[0];
27
- if (!k.startsWith('rack.')) {
28
- v = header[1];
29
- if (v.$$is_array) {
30
- v = v.join("\n");
31
- }
32
- bun_hdr.set(k, v);
30
+ v = header[1];
31
+ if (v.$$is_array) {
32
+ v = v.join("\n");
33
33
  }
34
+ bun_hdr.set(header[0].toLowerCase(), v);
34
35
  }
35
36
  }
36
37
  }
@@ -49,20 +50,93 @@ module Up
49
50
  def listen
50
51
  raise "already running" if @server
51
52
  %x{
52
- const oubr = Opal.Up.Bun.RackEnv;
53
53
  const oubs = Opal.Up.Bun.Server;
54
-
54
+ const ouwc = Opal.Up.Client;
55
+ const deco = new TextDecoder();
55
56
  var server_options = {
56
57
  port: #@port,
57
58
  hostname: #@host,
58
59
  development: false,
59
- fetch(req) {
60
- const rack_res = #@app.$call(oubr.$new(req, #@config));
61
- const hdr = new Headers();
62
- oubs.handle_headers(rack_res[1]);
60
+ fetch(req, server) {
61
+ const upgrade = req.headers.get('Upgrade');
62
+ const env = new Map();
63
+ env.set('rack.errors',#{STDERR});
64
+ env.set('rack.input', #@default_input);
65
+ env.set('rack.logger', #@logger);
66
+ env.set('rack.multipart.buffer_size', 4096);
67
+ env.set('rack.multipart.tempfile_factory', #@t_factory);
68
+ if (upgrade) {
69
+ env.set('rack.upgrade?', #{:websocket});
70
+ }
71
+ env.set('rack.url_scheme', #@scheme);
72
+ env.set('SCRIPT_NAME', "");
73
+ env.set('SERVER_PROTOCOL', req.httpVersion);
74
+ env.set('HTTP_VERSION', req.httpVersion);
75
+ env.set('SERVER_NAME', #@host);
76
+ env.set('SERVER_PORT', #@port);
77
+ env.set('QUERY_STRING', "");
78
+ env.set('REQUEST_METHOD', req.method);
79
+ env.set('PATH_INFO', req.url);
80
+ req.headers.forEach((k, v) => { env.set('HTTP_' + k.toUpperCase().replaceAll('-', '_'), v) });
81
+ const rack_res = #@app.$call(env);
82
+ if (upgrade) {
83
+ const handler = env.get('rack.upgrade');
84
+ if (rack_res[0] < 300 && handler && handler !== nil) {
85
+ const client = ouwc.$new();
86
+ client.env = env;
87
+ client.open = false;
88
+ client.handler = handler
89
+ client.protocol = #{:websocket};
90
+ client.server = server;
91
+ client.timeout = 120;
92
+ server.upgrade(req, { data: { client: client }});
93
+ return;
94
+ }
95
+ }
96
+ const hdrs = new Headers();
97
+ oubs.handle_headers(rack_res[1], hdrs);
63
98
  var body = '';
64
99
  body = oubs.handle_response(rack_res[2], body);
65
- return new Response(body, {status: rack_res[0], statusText: 'OK', headers: hdr});
100
+ return new Response(body, {status: rack_res[0], statusText: 'OK', headers: hdrs});
101
+ },
102
+ websocket: {
103
+ close: (ws) => {
104
+ const client = ws.data.client;
105
+ if (typeof(client.handler.$on_close) === 'function') {
106
+ client.ws = ws;
107
+ client.open = false;
108
+ client.handler.$on_close(client);
109
+ client.ws = null;
110
+ }
111
+ },
112
+ drain: (ws) => {
113
+ const client = ws.data.client;
114
+ if (typeof(client.handler.$on_drained) === 'function') {
115
+ client.ws = ws;
116
+ client.handler.$on_drained(client);
117
+ client.ws = null;
118
+ }
119
+ },
120
+ message: (ws, message) => {
121
+ const client = ws.data.client;
122
+ if (typeof(client.handler.$on_message) === 'function') {
123
+ if (typeof(message) !== 'string') {
124
+ message = deco.decode(message);
125
+ }
126
+ client.ws = ws;
127
+ client.handler.$on_message(client, message);
128
+ client.ws = null;
129
+ }
130
+ },
131
+ open: (ws) => {
132
+ const client = ws.data.client;
133
+ if (typeof(client.handler.$on_open) === 'function') {
134
+ client.ws = ws;
135
+ client.open = true;
136
+ client.handler.$on_open(client);
137
+ client.ws = null;
138
+ }
139
+ }
66
140
  }
67
141
  };
68
142
  if (#@scheme === 'https') {
data/lib/up/cli.rb CHANGED
@@ -32,6 +32,9 @@ module Up
32
32
  on('-k', '--key-file FILE', String, 'File with the servers certificate') do |key_file|
33
33
  options[:key_file] = key_file
34
34
  end
35
+ on('-l', '--log-file FILE', String, 'log file') do |log_file|
36
+ options[:logger] = Logger.new(File.new(log_file, 'a+'))
37
+ end
35
38
  on('-v', '--version', 'Show version') do
36
39
  puts "Up! v#{Up::VERSION}"
37
40
  exit
data/lib/up/client.rb ADDED
@@ -0,0 +1,68 @@
1
+ # backtick_javascript: true
2
+ if RUBY_ENGINE == 'opal'
3
+ %x{
4
+ const process = require('node:process');
5
+ }
6
+ end
7
+
8
+ module Up
9
+ class Client
10
+ # instance vars are set by the server
11
+
12
+ attr_reader :env, :handler, :protocol, :timeout
13
+
14
+ def handler=(h)
15
+ @handler.on_close(self)
16
+ @handler = h
17
+ @handler.on_open(self)
18
+ end
19
+
20
+ def open?
21
+ @open
22
+ end
23
+
24
+ def pubsub?
25
+ true
26
+ end
27
+
28
+ if RUBY_ENGINE == 'opal'
29
+ def close
30
+ @open = false
31
+ `#@ws?.close()`
32
+ end
33
+
34
+ def pending
35
+ return -1 unless @open
36
+ `#@ws?.getBufferedAmount()`
37
+ end
38
+
39
+ def publish(channel, message, engine = nil)
40
+ res = false
41
+ raise 'publish engine not supported' if engine
42
+ %x{
43
+ if (!message.$$is_string) {
44
+ message = JSON.stringify(message);
45
+ }
46
+ res = #@server?.publish(channel, message);
47
+ if (engine !== false && self.worker) {
48
+ process.send({c: channel, m: message});
49
+ }
50
+ }
51
+ res
52
+ end
53
+
54
+ def subscribe(channel, is_pattern = false, &block)
55
+ @sub_block = block
56
+ `#@ws?.subscribe(channel)`
57
+ end
58
+
59
+ def unsubscribe(channel, is_pattern = false)
60
+ `#@ws?.unsubscribe(channel)`
61
+ end
62
+
63
+ def write(data)
64
+ `#@ws?.send(data, false)`
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,39 @@
1
+ # backtick_javascript: true
2
+ require 'etc'
3
+ require 'random/formatter'
4
+ require 'up_ext'
5
+
6
+ module Up
7
+ module Ruby
8
+ class Cluster < Up::Ruby::Server
9
+ 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
+ super(app: app, host: host, port: port)
11
+ @secret = Random.uuid
12
+ @workers = workers || Etc.nprocessors
13
+ @members = []
14
+ end
15
+
16
+ def listen
17
+ raise "already running" unless @members.empty?
18
+ @workers.times do
19
+ @members << fork do
20
+ @member_id = @members.size + 1
21
+ super
22
+ end
23
+ end
24
+
25
+ Process.waitall
26
+ @members.each do |member|
27
+ Process.kill("KILL", member)
28
+ end
29
+ end
30
+
31
+ def stop
32
+ if Up::CLI::stoppable?
33
+ @members.each { |m| Process.kill(m) }
34
+ @members.clear
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
- require 'up/ruby/rack_env'
2
1
  require 'up_ext'
2
+ require 'up/ruby/cluster'
3
3
 
4
4
  module Up
5
5
  module Ruby
@@ -1,4 +1,3 @@
1
- require 'up/ruby/rack_env'
2
1
  require 'up_ext'
3
2
 
4
3
  module Up
@@ -2,6 +2,7 @@
2
2
  require 'up/u_web_socket/server'
3
3
 
4
4
  %x{
5
+ const process = require('node:process');
5
6
  const cluster = require('node:cluster');
6
7
  const num_workers = require('node:os').availableParallelism();
7
8
  }
@@ -9,8 +10,8 @@ require 'up/u_web_socket/server'
9
10
  module Up
10
11
  module UWebSocket
11
12
  class Cluster < Up::UWebSocket::Server
12
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, workers: nil)
13
- super(app: app, host: host, port: port, scheme: scheme, ca_file: ca_file, cert_file: cert_file, key_file: key_file)
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
+ super(app: app, host: host, port: port, scheme: scheme, ca_file: ca_file, cert_file: cert_file, key_file: key_file, logger: logger)
14
15
  @workers = workers || `num_workers`
15
16
  @members = []
16
17
  end
@@ -19,10 +20,24 @@ module Up
19
20
  raise "already running" unless @members.empty?
20
21
  %x{
21
22
  if (cluster.isPrimary) {
23
+ cluster.on('message', (worker, message, handle) => {
24
+ if (message.c && message.m) {
25
+ for (let member of #@members) {
26
+ if (member !== worker) {
27
+ member.send(message);
28
+ }
29
+ }
30
+ }
31
+ });
22
32
  for (let i = 0; i < #@workers; i++) {
23
- #@members.push(cluster.fork());
33
+ #@members[i] = cluster.fork();
24
34
  }
25
35
  } else {
36
+ self.worker = true;
37
+ function process_message_handler(message, handle) {
38
+ self.server.publish(message.c, message.m);
39
+ }
40
+ process.on('message', process_message_handler);
26
41
  #{super}
27
42
  }
28
43
  }
@@ -1,8 +1,10 @@
1
1
  # backtick_javascript: true
2
+ require 'logger'
2
3
  require 'up/cli'
3
- require 'up/u_web_socket/rack_env'
4
+ require 'up/client'
4
5
 
5
6
  %x{
7
+ const process = require('node:process');
6
8
  module.paths.push(process.cwd() + '/node_modules');
7
9
  const uws = require('uWebSockets.js');
8
10
  }
@@ -10,32 +12,32 @@ require 'up/u_web_socket/rack_env'
10
12
  module Up
11
13
  module UWebSocket
12
14
  class Server
13
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil)
15
+ def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
14
16
  @app = app
15
17
  @scheme = scheme || 'http'
16
18
  raise "unsupported scheme #{@scheme}" unless %w[http https].include?(@scheme)
17
19
  @host = host || 'localhost'
18
20
  @port = port&.to_i || 3000
19
- @config = { handler: self.class.name, engine: "node/#{`process.version`}", port: port, scheme: scheme, host: host }.freeze
21
+ @config = { handler: self.class.name, engine: "node/#{`process.version`}" }.freeze
20
22
  @ca_file = ca_file
21
23
  @cert_file = cert_file
22
24
  @key_file = key_file
23
- @server = nil
25
+ @default_input = IO.new
26
+ @server = nil
27
+ @logger = logger
28
+ @t_factory = proc { |filename, _content_type| File.new(filename, 'a+') }
24
29
  end
25
30
 
26
31
  %x{
27
32
  self.handle_headers = function(rack_headers, uws_res) {
28
33
  if (rack_headers.$$is_hash) {
29
- var header, k, v;
34
+ var header, v;
30
35
  for(header of rack_headers) {
31
- k = header[0];
32
- if (!k.startsWith('rack.')) {
33
- v = header[1];
34
- if (v.$$is_array) {
35
- v = v.join("\n");
36
- }
37
- uws_res.writeHeader(k, v);
36
+ v = header[1];
37
+ if (v.$$is_array) {
38
+ v = v.join("\n");
38
39
  }
40
+ uws_res.writeHeader(header[0].toLowerCase(), v);
39
41
  }
40
42
  }
41
43
  }
@@ -48,25 +50,116 @@ module Up
48
50
  }
49
51
  #{`parts`.close if `parts`.respond_to?(:close)}
50
52
  }
53
+
54
+ self.prepare_env = function(req) {
55
+ const env = new Map();
56
+ env.set('rack.errors',#{STDERR});
57
+ env.set('rack.input', #@default_input);
58
+ env.set('rack.logger', #@logger);
59
+ env.set('rack.multipart.buffer_size', 4096);
60
+ env.set('rack.multipart.tempfile_factory', #@t_factory);
61
+ env.set('rack.url_scheme', #@scheme);
62
+ env.set('SCRIPT_NAME', "");
63
+ env.set('SERVER_PROTOCOL', 'HTTP/1.1');
64
+ env.set('HTTP_VERSION', 'HTTP/1.1');
65
+ env.set('SERVER_NAME', #@host);
66
+ env.set('SERVER_PORT', #@port);
67
+ env.set('QUERY_STRING', req.getQuery());
68
+ env.set('REQUEST_METHOD', req.getMethod().toUpperCase());
69
+ env.set('PATH_INFO', req.getUrl());
70
+ req.forEach((k, v) => { env.set('HTTP_' + k.toUpperCase().replaceAll('-', '_'), v) });
71
+ return env;
72
+ }
51
73
  }
52
74
 
53
75
  def listen
54
76
  raise "already running" if @server
55
77
  %x{
56
- const ouwr = Opal.Up.UWebSocket.RackEnv;
57
78
  const ouws = Opal.Up.UWebSocket.Server;
79
+ const ouwc = Opal.Up.Client;
80
+ const deco = new TextDecoder();
58
81
  if (#@scheme == 'https') {
59
82
  #@server = uws.SSLApp({ ca_file_name: #@ca_file, cert_file_name: #@cert_file, key_file_name: #@key_file });
60
83
  } else {
61
84
  #@server = uws.App();
62
85
  }
63
86
  #@server.any('/*', (res, req) => {
64
- const rack_res = #@app.$call(ouwr.$new(req, #@config));
65
- res.writeStatus(`${rack_res[0].toString()} OK`);
87
+ const rack_res = #@app.$call(ouws.prepare_env(req));
88
+ res.writeStatus(rack_res[0].toString() + ' OK');
66
89
  ouws.handle_headers(rack_res[1], res);
67
90
  ouws.handle_response(rack_res[2], res);
68
91
  res.end();
69
92
  });
93
+ #@server.ws('/*', {
94
+ close: (ws, code, message) => {
95
+ const user_data = ws.getUserData();
96
+ if (typeof(user_data.client.handler.$on_close) === 'function') {
97
+ user_data.client.ws = ws;
98
+ user_data.client.open = false;
99
+ user_data.client.handler.$on_close(user_data.client);
100
+ user_data.client.ws = null;
101
+ }
102
+ },
103
+ drain: (ws) => {
104
+ const user_data = ws.getUserData();
105
+ if (typeof(user_data.client.handler.$on_drained) === 'function') {
106
+ user_data.client.ws = ws;
107
+ user_data.client.handler.$on_drained(user_data.client);
108
+ user_data.client.ws = null;
109
+ }
110
+ },
111
+ message: (ws, message, isBinary) => {
112
+ const user_data = ws.getUserData();
113
+ if (typeof(user_data.client.handler.$on_message) === 'function') {
114
+ const msg = deco.decode(message);
115
+ user_data.client.ws = ws;
116
+ user_data.client.handler.$on_message(user_data.client, msg);
117
+ user_data.client.ws = null;
118
+ }
119
+ },
120
+ open: (ws) => {
121
+ const user_data = ws.getUserData();
122
+ if (typeof(user_data.client.handler.$on_open) === 'function') {
123
+ user_data.client.ws = ws;
124
+ user_data.client.open = true;
125
+ user_data.client.handler.$on_open(user_data.client);
126
+ user_data.client.ws = null;
127
+ }
128
+ },
129
+ sendPingsAutomatically: true,
130
+ upgrade: (res, req, context) => {
131
+ const env = ouws.prepare_env(req);
132
+ env.set('rack.upgrade?', #{:websocket});
133
+ const rack_res = #@app.$call(env);
134
+ const handler = env.get('rack.upgrade');
135
+ if (rack_res[0] < 300 && handler && handler !== nil) {
136
+ const client = ouwc.$new();
137
+ client.env = env;
138
+ client.open = false;
139
+ client.handler = handler
140
+ client.protocol = #{:websocket};
141
+ client.server = self.server;
142
+ client.timeout = 120;
143
+ if (self.worker) {
144
+ client.worker = true;
145
+ }
146
+ res.upgrade({ client: client },
147
+ req.getHeader('sec-websocket-key'),
148
+ req.getHeader('sec-websocket-protocol'),
149
+ req.getHeader('sec-websocket-extensions'),
150
+ context);
151
+ } else {
152
+ if (rack_res[0] >= 300) {
153
+ env.delete('rack.upgrade');
154
+ }
155
+ res.writeStatus(rack_res[0].toString() + ' OK');
156
+ ouws.handle_headers(rack_res[1], res);
157
+ ouws.handle_response(rack_res[2], res);
158
+ res.end();
159
+ }
160
+ },
161
+
162
+ });
70
163
  #@server.listen(#@port, #@host, () => { console.log(`Server is running on ${#@scheme}://${#@host}:${#@port}`)});
71
164
  }
72
165
  end
data/lib/up/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Up
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.0.4'.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.3
4
+ version: 0.0.4
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-07 00:00:00.000000000 Z
11
+ date: 2024-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -127,8 +127,6 @@ executables:
127
127
  - up
128
128
  - up_bun
129
129
  - up_cluster
130
- - up_node
131
- - up_node_cluster
132
130
  - up_ruby
133
131
  - up_ruby_cluster
134
132
  extensions:
@@ -140,8 +138,6 @@ files:
140
138
  - bin/up
141
139
  - bin/up_bun
142
140
  - bin/up_cluster
143
- - bin/up_node
144
- - bin/up_node_cluster
145
141
  - bin/up_ruby
146
142
  - bin/up_ruby_cluster
147
143
  - ext/up_ext/App.h
@@ -191,23 +187,16 @@ files:
191
187
  - lib/up/bun/server.rb
192
188
  - lib/up/bun/server_cli.rb
193
189
  - lib/up/cli.rb
194
- - lib/up/node/cluster.rb
195
- - lib/up/node/cluster_cli.rb
196
- - lib/up/node/rack_cluster.rb
197
- - lib/up/node/rack_env.rb
198
- - lib/up/node/rack_server.rb
199
- - lib/up/node/server.rb
200
- - lib/up/node/server_cli.rb
190
+ - lib/up/client.rb
201
191
  - lib/up/rack_builder_patch.rb
192
+ - lib/up/ruby/cluster.rb
202
193
  - lib/up/ruby/cluster_cli.rb
203
194
  - lib/up/ruby/rack_cluster.rb
204
- - lib/up/ruby/rack_env.rb
205
195
  - lib/up/ruby/rack_server.rb
206
196
  - lib/up/ruby/server_cli.rb
207
197
  - lib/up/u_web_socket/cluster.rb
208
198
  - lib/up/u_web_socket/cluster_cli.rb
209
199
  - lib/up/u_web_socket/rack_cluster.rb
210
- - lib/up/u_web_socket/rack_env.rb
211
200
  - lib/up/u_web_socket/rack_server.rb
212
201
  - lib/up/u_web_socket/server.rb
213
202
  - lib/up/u_web_socket/server_cli.rb
data/bin/up_node DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- if RUBY_ENGINE == 'opal'
4
- require 'up/node/server_cli'
5
- Up::CLI.call
6
- else
7
- require 'up/cli'
8
- Up::CLI.setup_node
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_node_cluster DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- if RUBY_ENGINE == 'opal'
4
- require 'up/node/cluster_cli'
5
- Up::CLI.call
6
- else
7
- require 'up/cli'
8
- Up::CLI.setup_node
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
@@ -1,39 +0,0 @@
1
- # backtick_javascript: true
2
- require 'up/node/server'
3
-
4
- %x{
5
- const cluster = require('node:cluster');
6
- const num_workers = require('node:os').availableParallelism();
7
- }
8
-
9
- module Up
10
- module Node
11
- class Cluster < Up::Node::Server
12
- def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, workers: nil)
13
- super(app: app, host: host, port: port, scheme: scheme, ca_file: ca_file, cert_file: cert_file, key_file: key_file)
14
- @workers = workers || `num_workers`
15
- @members = []
16
- end
17
-
18
- def listen
19
- raise "already running" unless @members.empty?
20
- %x{
21
- if (cluster.isPrimary) {
22
- for (let i = 0; i < #@workers; i++) {
23
- #@members.push(cluster.fork());
24
- }
25
- } else {
26
- #{super}
27
- }
28
- }
29
- end
30
-
31
- def stop
32
- if Up::CLI::stoppable?
33
- @members.each { |m| `m.kill()` }
34
- @members.clear
35
- end
36
- end
37
- end
38
- end
39
- 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/node/rack_cluster'
8
-
9
- module Up
10
- module CLI
11
- def self.call
12
- Up::Node::RackCluster.run(get_app, get_options)
13
- end
14
- end
15
- end