opal-up 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/ext/up_ext/up_ext.c CHANGED
@@ -3,6 +3,7 @@
3
3
  #include <arpa/inet.h>
4
4
  #include <ruby.h>
5
5
  #include <ruby/encoding.h>
6
+ #include <signal.h>
6
7
  #include <sys/socket.h>
7
8
  #include <sys/wait.h>
8
9
  #include <unistd.h>
@@ -65,6 +66,10 @@ static VALUE SERVER_NAME;
65
66
  static VALUE SERVER_PORT;
66
67
  static VALUE SERVER_PROTOCOL;
67
68
 
69
+ // both used when worker of a cluster
70
+ uws_app_t *cluster_app;
71
+ struct us_listen_socket_t *cluster_socket;
72
+
68
73
  #define set_str_val(gl_name, str) \
69
74
  rb_gc_register_address(&gl_name); \
70
75
  (gl_name) = rb_enc_str_new((str), strlen((str)), binary_encoding); \
@@ -358,12 +363,23 @@ response_error:
358
363
  uws_res_end_without_body(USE_SSL, res, false);
359
364
  }
360
365
 
366
+ static void
367
+ up_server_cluster_listen_handler(struct us_listen_socket_t *listen_socket,
368
+ uws_app_listen_config_t config, void *arg) {
369
+ if (listen_socket) {
370
+ cluster_socket = listen_socket;
371
+ fprintf(stderr, "Internal Cluster communication on http://localhost:%d\n",
372
+ config.port);
373
+ }
374
+ }
375
+
361
376
  static void up_server_listen_handler(struct us_listen_socket_t *listen_socket,
362
377
  uws_app_listen_config_t config,
363
- void *user_data) {
364
- if (listen_socket)
365
- fprintf(stderr, "Server is running on http://%s:%d\n", config.host,
378
+ void *arg) {
379
+ if (listen_socket) {
380
+ fprintf(stderr, "Server is listening on http://%s:%d\n", config.host,
366
381
  config.port);
382
+ }
367
383
  }
368
384
 
369
385
  const rb_data_type_t up_client_t = {.wrap_struct_name = "Up::Client",
@@ -721,6 +737,13 @@ upgrade_error:
721
737
  fprintf(stderr, "upgrade error");
722
738
  }
723
739
 
740
+ static void up_internal_close_sockets(int signal) {
741
+ if (cluster_socket)
742
+ us_listen_socket_close(false, cluster_socket);
743
+ if (cluster_app)
744
+ uws_app_close(USE_SSL, cluster_app);
745
+ }
746
+
724
747
  static VALUE up_server_listen(VALUE self) {
725
748
  server_s *s = DATA_PTR(self);
726
749
  up_internal_check_arg_types(s->rapp, &s->host, &s->port);
@@ -747,8 +770,16 @@ static VALUE up_server_listen(VALUE self) {
747
770
  .port = FIX2INT(s->port), .host = RSTRING_PTR(s->host), .options = 0};
748
771
  VALUE rmember_id = rb_ivar_get(self, at_member_id);
749
772
  if (rmember_id != Qnil) {
773
+ // got a cluster
750
774
  s->member_id = FIX2INT(rmember_id);
751
- // got a cluster, open publish ports
775
+ // install signal handler
776
+ cluster_app = s->app;
777
+ cluster_socket = NULL;
778
+ struct sigaction upclcl = {.sa_handler = up_internal_close_sockets,
779
+ .sa_flags = 0};
780
+ sigemptyset(&upclcl.sa_mask);
781
+ sigaction(SIGINT, &upclcl, NULL);
782
+ // open publish ports
752
783
  VALUE rworkers = rb_ivar_get(self, at_workers);
753
784
  s->workers = FIX2INT(rworkers);
754
785
  VALUE rsecret = rb_ivar_get(self, at_secret);
@@ -761,7 +792,14 @@ static VALUE up_server_listen(VALUE self) {
761
792
  uws_app_listen_config_t config_internal = {
762
793
  .port = config.port + s->member_id, .host = "localhost", .options = 0};
763
794
  uws_app_listen_with_config(false, s->app, config_internal,
764
- up_server_listen_handler, NULL);
795
+ up_server_cluster_listen_handler, NULL);
796
+ } else {
797
+ cluster_app = s->app;
798
+ cluster_socket = NULL;
799
+ struct sigaction upclcl = {.sa_handler = up_internal_close_sockets,
800
+ .sa_flags = 0};
801
+ sigemptyset(&upclcl.sa_mask);
802
+ sigaction(SIGINT, &upclcl, NULL);
765
803
  }
766
804
  uws_app_any(USE_SSL, s->app, "/*", up_server_request_handler, (void *)s);
767
805
  uws_ws(USE_SSL, s->app, "/*",
@@ -21,18 +21,41 @@ module Up
21
21
  super
22
22
  end
23
23
  end
24
-
25
- Process.waitall
26
- @members.each do |member|
27
- Process.kill("KILL", member)
24
+ unless @member_id
25
+ install_signal_handlers
26
+ Process.waitall
28
27
  end
29
28
  end
30
29
 
31
30
  def stop
32
31
  if Up::CLI::stoppable?
33
- @members.each { |m| Process.kill(m) }
34
- @members.clear
32
+ kill_members
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def install_signal_handlers
39
+ Signal.trap('CHLD') do
40
+ warn "\nError: a cluster member died!"
41
+ kill_members
42
+ end
43
+ Signal.trap('INT') do
44
+ warn "\nReceived CTRL-C!"
45
+ kill_members
46
+ end
47
+ end
48
+
49
+ def kill_members
50
+ Signal.trap('CHLD', 'IGNORE')
51
+ STDERR.print "Stopping workers: "
52
+ @members.each do |mid|
53
+ Process.kill('INT', mid) rescue nil
54
+ STDERR.print '.'
35
55
  end
56
+ @members.clear
57
+ warn "\nCluster stopped."
58
+ Signal.trap('CHLD', 'DEFAULT')
36
59
  end
37
60
  end
38
61
  end
data/lib/up/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Up
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.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.4
4
+ version: 0.0.5
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-12 00:00:00.000000000 Z
11
+ date: 2024-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger