opal-up 0.0.5 → 0.0.6

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: 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: []