opal-up 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd09c3697caf76eb487770a2818af0a06ee4711761a15f2d80d7d0d291747234
4
- data.tar.gz: cc53773debbd42d66a2aa99e1b3d9ec3e3fcd05db99f5e58bfab94e5ecf1811a
3
+ metadata.gz: e47b86e6f54cbdb8ecf23cf5b6c759127ac30a8f4f00764e39eeca57ca94e52d
4
+ data.tar.gz: 6d93f3b96474fb1c18fadeb5a46083241947691470a0c3f7d36dc7025e1116de
5
5
  SHA512:
6
- metadata.gz: 38c374376cfe497c4abd8039272ae616d44e5152d3ba15fc47578d789bd16d88cf8af21d2471fd71eafa0e3852f60704a0aabf03dd560bac2de5c87591724d1a
7
- data.tar.gz: 0467d90a76aedd75515f38c678ce7cdcac7e36760a687c9ae6283dfdd9723ea2d0e005d67e357fbcf60491c594511c45be105002a008f650c2eb488f5f315c53
6
+ metadata.gz: 25d3c86c354d50656b266995a0d235460e6d9c45b1853d33d363636e1bead3b4539b8a068fee0cbfd58b27d2160759b2f1823ae039c2ce0c15793f6a95fd0541
7
+ data.tar.gz: d3a6dd3a8e854a1ba75cfc297ecb5b4153c04b3814185add67424bcfd7574538d4365aebbd1006967e798d7af155ad0b98582955eb4f8c2e1f5633448d474433
data/README.md CHANGED
@@ -84,15 +84,16 @@ Available with `bundle exec` within the example apps or if this gem is included
84
84
  Usage: up [options]
85
85
 
86
86
  -h, --help Show this message
87
- -p, --port PORT Port number the server will listen to
88
- -b, --bind ADDRESS Address the server will listen to
87
+ -p, --port PORT Port number the server will listen to. Default: 3000
88
+ -b, --bind ADDRESS Address the server will listen to. Default: localhost
89
89
  -s, --secure Use secure sockets.
90
90
  When using secure sockets, the -a, -c and -k options must be provided
91
91
  -a, --ca-file FILE File with CA certs
92
92
  -c, --cert-file FILE File with the servers certificate
93
93
  -k, --key-file FILE File with the servers certificate
94
+ -l, --log-file FILE Log file
94
95
  -v, --version Show version
95
-
96
+ -w, --workers NUMBER For clusters, the number of workers to run. Default: number of processors
96
97
  ```
97
98
  ## Supported Features
98
99
 
data/ext/up_ext/up_ext.c CHANGED
@@ -22,7 +22,9 @@ static VALUE cLogger;
22
22
 
23
23
  static ID at_env;
24
24
  static ID at_handler;
25
+ static ID at_instance;
25
26
  static ID at_member_id;
27
+ static ID at_members;
26
28
  static ID at_open;
27
29
  static ID at_protocol;
28
30
  static ID at_secret;
@@ -40,6 +42,7 @@ static ID id_on_drained;
40
42
  static ID id_on_message;
41
43
  static ID id_on_open;
42
44
  static ID id_port;
45
+ static ID id_publish;
43
46
 
44
47
  static rb_encoding *utf8_encoding;
45
48
  static rb_encoding *binary_encoding;
@@ -411,14 +414,14 @@ static VALUE up_client_pending(VALUE self) {
411
414
  return INT2FIX(0);
412
415
  }
413
416
 
414
- static void up_client_cluster_publish(server_s *s, int st, VALUE channel,
417
+ static void up_client_cluster_publish(char *scrt, int st, VALUE channel,
415
418
  VALUE message) {
416
419
  const char *opening_line = "POST " INTERNAL_PUBLISH_PATH " HTTP/1.1\r\n";
417
420
  const char *host_header = "Host: localhost\r\n";
418
421
  const char *secret = "Secret: ";
419
422
  char secret_header[50];
420
423
  memcpy(secret_header, secret, 8);
421
- memcpy(secret_header + 8, s->secret, 36);
424
+ memcpy(secret_header + 8, scrt, 36);
422
425
  memcpy(secret_header + 8 + 36, "\r\n", 2);
423
426
  const char *content_type = "Content-Type: text/plain\r\n";
424
427
  long c_length = RSTRING_LEN(channel) + RSTRING_LEN(message) + 2;
@@ -447,12 +450,25 @@ static void up_client_cluster_publish(server_s *s, int st, VALUE channel,
447
450
  // fprintf(stderr, "read: %s\n", read_buf);
448
451
  }
449
452
 
450
- static VALUE up_client_publish(int argc, VALUE *argv, VALUE self) {
453
+ static void up_internal_publish_to_member(server_s *s, VALUE channel,
454
+ VALUE message, int member_idx) {
455
+ struct sockaddr_in member_addr = {.sin_addr.s_addr = inet_addr("127.0.0.1"),
456
+ .sin_family = AF_INET};
457
+ int st = socket(AF_INET, SOCK_STREAM, 0);
458
+ if (st) {
459
+ member_addr.sin_port = htons(FIX2INT(s->port) + member_idx);
460
+ if (connect(st, (struct sockaddr *)&member_addr,
461
+ sizeof(struct sockaddr_in)) == 0) {
462
+ up_client_cluster_publish(s->secret, st, channel, message);
463
+ close(st);
464
+ }
465
+ }
466
+ }
467
+
468
+ static VALUE up_client_publish(VALUE self, VALUE channel, VALUE message) {
451
469
  uws_websocket_t *ws = DATA_PTR(self);
452
470
  if (!ws)
453
471
  return Qnil;
454
- VALUE channel, message, engine;
455
- rb_scan_args(argc, argv, "21", &channel, &message, &engine);
456
472
  if (TYPE(channel) != T_STRING)
457
473
  channel = rb_obj_as_string(channel);
458
474
  if (TYPE(message) != T_STRING)
@@ -467,20 +483,9 @@ static VALUE up_client_publish(int argc, VALUE *argv, VALUE self) {
467
483
 
468
484
  // publish to cluster members
469
485
  int i;
470
- struct sockaddr_in member_addr = {
471
- .sin_addr.s_addr = inet_addr("127.0.0.1"), .sin_family = AF_INET};
472
486
  for (i = 1; i <= s->workers; i++) {
473
- if (i != s->member_id) {
474
- int st = socket(AF_INET, SOCK_STREAM, 0);
475
- if (st) {
476
- member_addr.sin_port = htons(FIX2INT(s->port) + i);
477
- if (connect(st, (struct sockaddr *)&member_addr,
478
- sizeof(struct sockaddr_in)) == 0) {
479
- up_client_cluster_publish(s, st, channel, message);
480
- close(st);
481
- }
482
- }
483
- }
487
+ if (i != s->member_id)
488
+ up_internal_publish_to_member(s, channel, message, i);
484
489
  }
485
490
  }
486
491
  return res ? Qtrue : Qfalse;
@@ -747,6 +752,7 @@ static void up_internal_close_sockets(int signal) {
747
752
  static VALUE up_server_listen(VALUE self) {
748
753
  server_s *s = DATA_PTR(self);
749
754
  up_internal_check_arg_types(s->rapp, &s->host, &s->port);
755
+ rb_ivar_set(mUp, at_instance, self);
750
756
 
751
757
  s->env_template = rb_hash_dup(rack_env_template);
752
758
  // When combined with SCRIPT_NAME and PATH_INFO, these variables can be used
@@ -820,6 +826,33 @@ static VALUE up_server_listen(VALUE self) {
820
826
  return self;
821
827
  }
822
828
 
829
+ static VALUE up_server_publish(VALUE self, VALUE channel, VALUE message) {
830
+ if (TYPE(channel) != T_STRING)
831
+ channel = rb_obj_as_string(channel);
832
+ if (TYPE(message) != T_STRING)
833
+ message = rb_obj_as_string(message);
834
+ server_s *s = DATA_PTR(self);
835
+ VALUE members = rb_ivar_get(self, at_members);
836
+ if (members != Qnil) {
837
+ long i, mb_cnt = RARRAY_LEN(members);
838
+ for (i = 0; i < mb_cnt; i++) {
839
+ up_internal_publish_to_member(s, channel, message, i);
840
+ }
841
+ } else {
842
+ uws_publish(USE_SSL, s->app, RSTRING_PTR(channel), RSTRING_LEN(channel),
843
+ RSTRING_PTR(message), RSTRING_LEN(message), TEXT, false);
844
+ if (s->member_id > 0) {
845
+ // publish to cluster members
846
+ int i;
847
+ for (i = 1; i <= s->workers; i++) {
848
+ if (i != s->member_id)
849
+ up_internal_publish_to_member(s, channel, message, i);
850
+ }
851
+ }
852
+ }
853
+ return Qtrue;
854
+ }
855
+
823
856
  static VALUE up_server_stop(VALUE self) {
824
857
  server_s *s = DATA_PTR(self);
825
858
  if (!s->app)
@@ -891,10 +924,19 @@ void up_setup_rack_env_template(void) {
891
924
  rb_hash_aset(rack_env_template, HTTP_VERSION, http11);
892
925
  }
893
926
 
927
+ static VALUE up_publish(VALUE self, VALUE channel, VALUE message) {
928
+ VALUE instance = rb_ivar_get(mUp, at_instance);
929
+ if (instance != Qnil)
930
+ return rb_funcall(instance, id_publish, 2, channel, message);
931
+ return Qfalse;
932
+ }
933
+
894
934
  void Init_up_ext(void) {
895
935
  at_env = rb_intern("@env");
896
936
  at_handler = rb_intern("@handler");
937
+ at_instance = rb_intern("@instance");
897
938
  at_member_id = rb_intern("@member_id");
939
+ at_members = rb_intern("@members");
898
940
  at_open = rb_intern("@open");
899
941
  at_protocol = rb_intern("@protocol");
900
942
  at_secret = rb_intern("@secret");
@@ -912,6 +954,7 @@ void Init_up_ext(void) {
912
954
  id_on_message = rb_intern("on_message");
913
955
  id_on_open = rb_intern("on_open");
914
956
  id_port = rb_intern("port");
957
+ id_publish = rb_intern("publish");
915
958
 
916
959
  utf8_encoding = rb_enc_find("UTF-8");
917
960
  binary_encoding = rb_enc_find("binary");
@@ -949,11 +992,13 @@ void Init_up_ext(void) {
949
992
  up_setup_rack_env_template();
950
993
 
951
994
  mUp = rb_define_module("Up");
995
+ rb_define_singleton_method(mUp, "publish", up_publish, 2);
996
+
952
997
  cClient = rb_define_class_under(mUp, "Client", rb_cObject);
953
998
  rb_define_alloc_func(cClient, up_client_alloc);
954
999
  rb_define_method(cClient, "close", up_client_close, 0);
955
1000
  rb_define_method(cClient, "pending", up_client_pending, 0);
956
- rb_define_method(cClient, "publish", up_client_publish, -1);
1001
+ rb_define_method(cClient, "publish", up_client_publish, 2);
957
1002
  rb_define_method(cClient, "subscribe", up_client_subscribe, -1);
958
1003
  rb_define_method(cClient, "unsubscribe", up_client_unsubscribe, -1);
959
1004
  rb_define_method(cClient, "write", up_client_write, 1);
@@ -964,5 +1009,6 @@ void Init_up_ext(void) {
964
1009
  rb_define_alloc_func(cServer, up_server_alloc);
965
1010
  rb_define_method(cServer, "initialize", up_server_init, -1);
966
1011
  rb_define_method(cServer, "listen", up_server_listen, 0);
1012
+ rb_define_method(cServer, "publish", up_server_publish, 2);
967
1013
  rb_define_method(cServer, "stop", up_server_stop, 0);
968
1014
  }
data/lib/up/bun/server.rb CHANGED
@@ -4,6 +4,13 @@ require 'up/cli'
4
4
  require 'up/client'
5
5
 
6
6
  module Up
7
+ class << self
8
+ def publish(channel, message)
9
+ raise 'no instance running' unless @instance
10
+ @instance&.publish(channel, message)
11
+ end
12
+ end
13
+
7
14
  module Bun
8
15
  class Server
9
16
  def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
@@ -49,6 +56,7 @@ module Up
49
56
  }
50
57
  def listen
51
58
  raise "already running" if @server
59
+ ::Up.instance_variable_set(:@instance, self)
52
60
  %x{
53
61
  const oubs = Opal.Up.Bun.Server;
54
62
  const ouwc = Opal.Up.Client;
@@ -152,6 +160,15 @@ module Up
152
160
  }
153
161
  end
154
162
 
163
+ def publish(channel, message)
164
+ %x{
165
+ if (!message.$$is_string) {
166
+ message = JSON.stringify(message);
167
+ }
168
+ #@server.publish(channel, message);
169
+ }
170
+ end
171
+
155
172
  def stop
156
173
  if Up::CLI::stoppable?
157
174
  `#@server.stop()`
data/lib/up/cli.rb CHANGED
@@ -14,10 +14,10 @@ module Up
14
14
  puts self
15
15
  exit
16
16
  end
17
- on('-p', '--port PORT', String, 'Port number the server will listen to') do |port|
17
+ on('-p', '--port PORT', String, 'Port number the server will listen to. Default: 3000') do |port|
18
18
  options[:port] = port.to_i
19
19
  end
20
- on('-b', '--bind ADDRESS', String, 'Address the server will listen to') do |host|
20
+ on('-b', '--bind ADDRESS', String, 'Address the server will listen to. Default: localhost') do |host|
21
21
  options[:host] = host
22
22
  end
23
23
  on('-s', '--secure', "Use secure sockets.\nWhen using secure sockets, the -a, -c and -k options must be provided") do
@@ -32,13 +32,16 @@ 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|
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
38
  on('-v', '--version', 'Show version') do
39
39
  puts "Up! v#{Up::VERSION}"
40
40
  exit
41
41
  end
42
+ on('-w', '--workers NUMBER', 'For clusters, the number of workers to run. Default: number of processors') do |workers|
43
+ options[:workers] = workers.to_i
44
+ end
42
45
  end
43
46
 
44
47
  def parse!
data/lib/up/client.rb CHANGED
@@ -36,15 +36,14 @@ module Up
36
36
  `#@ws?.getBufferedAmount()`
37
37
  end
38
38
 
39
- def publish(channel, message, engine = nil)
39
+ def publish(channel, message)
40
40
  res = false
41
- raise 'publish engine not supported' if engine
42
41
  %x{
43
42
  if (!message.$$is_string) {
44
43
  message = JSON.stringify(message);
45
44
  }
46
45
  res = #@server?.publish(channel, message);
47
- if (engine !== false && self.worker) {
46
+ if (#@worker) {
48
47
  process.send({c: channel, m: message});
49
48
  }
50
49
  }
@@ -15,6 +15,7 @@ module Up
15
15
 
16
16
  def listen
17
17
  raise "already running" unless @members.empty?
18
+ ::Up.instance_variable_set(:@instance, self)
18
19
  @workers.times do
19
20
  @members << fork do
20
21
  @member_id = @members.size + 1
@@ -18,6 +18,7 @@ module Up
18
18
 
19
19
  def listen
20
20
  raise "already running" unless @members.empty?
21
+ ::Up.instance_variable_set(:@instance, self)
21
22
  %x{
22
23
  if (cluster.isPrimary) {
23
24
  cluster.on('message', (worker, message, handle) => {
@@ -33,9 +34,9 @@ module Up
33
34
  #@members[i] = cluster.fork();
34
35
  }
35
36
  } else {
36
- self.worker = true;
37
+ #@worker = true;
37
38
  function process_message_handler(message, handle) {
38
- self.server.publish(message.c, message.m);
39
+ #@server.publish(message.c, message.m);
39
40
  }
40
41
  process.on('message', process_message_handler);
41
42
  #{super}
@@ -43,6 +44,25 @@ module Up
43
44
  }
44
45
  end
45
46
 
47
+ def publish(channel, message)
48
+ %x{
49
+ if (!message.$$is_string) {
50
+ message = JSON.stringify(message);
51
+ }
52
+ if (#@worker ) {
53
+ #@server?.publish(channel, message);
54
+ process.send({c: channel, m: message});
55
+ } else if (#@members) {
56
+ for (let member of #@members) {
57
+ if (member !== worker) {
58
+ member.send(message);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ true
64
+ end
65
+
46
66
  def stop
47
67
  if Up::CLI::stoppable?
48
68
  @members.each { |m| `m.kill()` }
@@ -10,6 +10,13 @@ require 'up/client'
10
10
  }
11
11
 
12
12
  module Up
13
+ class << self
14
+ def publish(channel, message)
15
+ raise 'no instance running' unless @instance
16
+ @instance&.publish(channel, message)
17
+ end
18
+ end
19
+
13
20
  module UWebSocket
14
21
  class Server
15
22
  def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
@@ -74,6 +81,7 @@ module Up
74
81
 
75
82
  def listen
76
83
  raise "already running" if @server
84
+ ::Up.instance_variable_set(:@instance, self)
77
85
  %x{
78
86
  const ouws = Opal.Up.UWebSocket.Server;
79
87
  const ouwc = Opal.Up.Client;
@@ -138,9 +146,9 @@ module Up
138
146
  client.open = false;
139
147
  client.handler = handler
140
148
  client.protocol = #{:websocket};
141
- client.server = self.server;
149
+ client.server = #@server;
142
150
  client.timeout = 120;
143
- if (self.worker) {
151
+ if (#@worker) {
144
152
  client.worker = true;
145
153
  }
146
154
  res.upgrade({ client: client },
@@ -164,6 +172,15 @@ module Up
164
172
  }
165
173
  end
166
174
 
175
+ def publish(channel, message)
176
+ %x{
177
+ if (!message.$$is_string) {
178
+ message = JSON.stringify(message);
179
+ }
180
+ #@server.publish(channel, message);
181
+ }
182
+ end
183
+
167
184
  def stop
168
185
  if Up::CLI::stoppable?
169
186
  `#@server.close()`
data/lib/up/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Up
2
- VERSION = '0.0.5'.freeze
2
+ VERSION = '0.0.6'.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.5
4
+ version: 0.0.6
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-14 00:00:00.000000000 Z
11
+ date: 2024-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -58,26 +58,6 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 3.0.9
61
- - !ruby/object:Gem::Dependency
62
- name: rackup
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: 0.2.2
68
- - - "<"
69
- - !ruby/object:Gem::Version
70
- version: 3.0.0
71
- type: :runtime
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: 0.2.2
78
- - - "<"
79
- - !ruby/object:Gem::Version
80
- version: 3.0.0
81
61
  - !ruby/object:Gem::Dependency
82
62
  name: rake
83
63
  requirement: !ruby/object:Gem::Requirement
@@ -201,7 +181,7 @@ files:
201
181
  - lib/up/u_web_socket/server.rb
202
182
  - lib/up/u_web_socket/server_cli.rb
203
183
  - lib/up/version.rb
204
- homepage: ''
184
+ homepage: https://github.com/janbiedermann/up
205
185
  licenses:
206
186
  - MIT
207
187
  metadata: {}
@@ -223,5 +203,5 @@ requirements: []
223
203
  rubygems_version: 3.5.3
224
204
  signing_key:
225
205
  specification_version: 4
226
- summary: Rack server for Opal
206
+ summary: Rack server for Opal and Ruby
227
207
  test_files: []