rage-iodine 3.0.0 → 3.0.2

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: 15eb3d0d5e2834bc02a3e116dd07cd2fa36a73ad56ff7812579f1406a6d2874a
4
- data.tar.gz: 3d9c061fe439e73a262a3c6ce0cd07f56d3ba2226b309caec539e202701e2249
3
+ metadata.gz: d96bd1cba30c10ee53b362f816e5c59fc05e16daecce52d294fd7fcb2f7d3727
4
+ data.tar.gz: aca815f5c9b722980cd94bd176b492d83888133f02eaa84aa4d04cc5275443eb
5
5
  SHA512:
6
- metadata.gz: 2b8d6ed6f9372e1cbfdd089de2e6d9941e2ef20da98ac5f47e603bcd5369ea4afb51b89fb7e80e01869f4752a8679bcf094d60f3a29930641c98fabe2c3481d9
7
- data.tar.gz: 39f880d839140587dde14e5e1fa3b68bdbb0e35db97333de28a0d024d9d3c8b18cb3575098baeaa813cfc8eb03b459e3042bf6a70aeeec5f57b60557eafddb38
6
+ metadata.gz: 26ad4b2eb5ebf8e3bc0ae5985b706a5126e9cddda0052e0bed5669979f794f71c7c2039a2dc867e38d00d7b06cd2d5954340821e8a725a3895d1ccf1cbac4d79
7
+ data.tar.gz: e4a708af24640800d5e86c2b0acfaaaaaddbfaeba1c818c9028a607de63898cc5eed57a244d74e935636c260e57b7ee54c02b44e219c2dbffdbc1be574a292de
data/CHANGELOG.md CHANGED
@@ -6,9 +6,19 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+ #### Change log v.3.0.2 (2023-12-18)
10
+
11
+ **Fix**: Correctly set timeout option.
12
+ **Fix**: Correctly set max_clients option.
13
+
14
+ #### Change log v.3.0.1 (2023-12-11)
15
+
16
+ **Fix**: Disable scheduling request fibers.
17
+
9
18
  #### Change log v.3.0.0 (2023-12-09)
10
19
 
11
20
  **Update**: Schedule request fibers.
21
+ **Update**: Improve stability and memory management under high load.
12
22
 
13
23
  #### Change log v.2.3.0 (2023-11-27)
14
24
 
data/Gemfile CHANGED
@@ -5,7 +5,6 @@ group :test do
5
5
  gem 'rspec'
6
6
  gem 'rack'
7
7
  gem 'http'
8
- gem "rage-rb"
9
8
  end
10
9
 
11
10
  # Specify your gem's dependencies in iodine.gemspec
@@ -106,7 +106,7 @@ static inline void http_s_new(http_s *h, http_fio_protocol_s *owner,
106
106
  },
107
107
  .headers = fiobj_hash_new(),
108
108
  .received_at = fio_last_tick(),
109
- .status = 200
109
+ .status = 200,
110
110
  };
111
111
  }
112
112
 
data/ext/iodine/iodine.c CHANGED
@@ -826,7 +826,7 @@ FIO_FUNC iodine_connection_args_s iodine_connect_args(VALUE s, uint8_t is_srv) {
826
826
  service = rb_sym2str(service);
827
827
  service_str = IODINE_RSTRINFO(service);
828
828
  }
829
- if (timeout != Qnil && RB_TYPE_P(ping, T_FIXNUM)) {
829
+ if (timeout != Qnil && RB_TYPE_P(timeout, T_FIXNUM)) {
830
830
  if (FIX2ULONG(timeout) > 255)
831
831
  FIO_LOG_WARNING(":timeout value over 255 will be silently ignored.");
832
832
  else
@@ -60,9 +60,8 @@ static ID each_method_id;
60
60
  static ID attach_method_id;
61
61
  static ID iodine_call_proc_id;
62
62
  static ID fiber_result_var_id;
63
+ static VALUE http_wait_directive;
63
64
  static ID fiber_id_method_id;
64
- static VALUE rb_cFiber;
65
- static ID schedule_method_id;
66
65
 
67
66
  static VALUE env_template_no_upgrade;
68
67
  static VALUE env_template_websockets;
@@ -120,6 +119,7 @@ typedef struct {
120
119
  IODINE_HTTP_XSENDFILE,
121
120
  IODINE_HTTP_EMPTY,
122
121
  IODINE_HTTP_ERROR,
122
+ IODINE_HTTP_WAIT,
123
123
  IODINE_HTTP_DEFERRED,
124
124
  } type;
125
125
  enum iodine_upgrade_type_enum {
@@ -679,7 +679,6 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
679
679
  goto err_not_found;
680
680
 
681
681
  if (handle->type == IODINE_HTTP_DEFERRED) {
682
- // the deferred response is now ready so fetch it from the fiber
683
682
  rbresponse = rb_ivar_get((VALUE)h->fiber, fiber_result_var_id);
684
683
  } else {
685
684
  // create / register env variable
@@ -688,13 +687,8 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
688
687
  tmp = IodineRackIO.create(h, env);
689
688
  // pass env variable to handler
690
689
  rbresponse = IodineCaller.call2((VALUE)h->udata, iodine_call_proc_id, 1, &env);
691
- IodineStore.add(rbresponse);
692
690
  // close rack.io
693
691
  IodineRackIO.close(tmp);
694
-
695
- // if there's a fiber in the http_s object means the request has to be deferred
696
- if (h->fiber)
697
- goto defer;
698
692
  }
699
693
 
700
694
  // test handler's return value
@@ -703,6 +697,13 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
703
697
  }
704
698
 
705
699
  tmp = rb_ary_entry(rbresponse, 0);
700
+ // rack will return `[:__http_defer__, fiber_to_wait_on]` in case the request needs to be paused
701
+ if (TYPE(tmp) == T_SYMBOL && tmp == http_wait_directive) {
702
+ h->fiber = (void *)IodineStore.add(rb_ary_entry(rbresponse, 1));
703
+ goto defer;
704
+ }
705
+
706
+ IodineStore.add(rbresponse);
706
707
  // set response status
707
708
  if (TYPE(tmp) == T_STRING) {
708
709
  char *data = RSTRING_PTR(tmp);
@@ -741,7 +742,8 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
741
742
  // review each header and write it to the response.
742
743
  rb_hash_foreach(response_headers, for_each_header_data, (VALUE)(h));
743
744
  // review for upgrade.
744
- if (handle->type != IODINE_HTTP_DEFERRED && (intptr_t)h->status < 300 && ruby2c_review_upgrade(handle, rbresponse, env))
745
+ if (handle->type != IODINE_HTTP_DEFERRED && (intptr_t)h->status < 300 &&
746
+ ruby2c_review_upgrade(handle, rbresponse, env))
745
747
  goto external_done;
746
748
  // send the request body.
747
749
  if (ruby2c_response_send(handle, rbresponse, env))
@@ -750,31 +752,32 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
750
752
  finish:
751
753
  IodineStore.remove(rbresponse);
752
754
  IodineStore.remove(env);
753
- return (void *)rbresponse;
755
+ return NULL;
754
756
 
755
757
  external_done:
756
758
  IodineStore.remove(rbresponse);
757
759
  IodineStore.remove(env);
758
760
  handle->type = IODINE_HTTP_NONE;
759
- return (void *)rbresponse;
761
+ return NULL;
760
762
 
761
763
  err_not_found:
762
764
  IodineStore.remove(rbresponse);
763
765
  IodineStore.remove(env);
764
766
  h->status = 404;
765
767
  handle->type = IODINE_HTTP_ERROR;
766
- return (void *)rbresponse;
768
+ return NULL;
767
769
 
768
770
  internal_error:
769
771
  IodineStore.remove(rbresponse);
770
772
  IodineStore.remove(env);
771
773
  h->status = 500;
772
774
  handle->type = IODINE_HTTP_ERROR;
773
- return (void *)rbresponse;
775
+ return NULL;
774
776
 
775
777
  defer:
776
778
  IodineStore.remove(env);
777
- return (void *)rbresponse;
779
+ handle->type = IODINE_HTTP_WAIT;
780
+ return NULL;
778
781
  }
779
782
 
780
783
  static inline void
@@ -823,10 +826,11 @@ static inline void http_resume_deferred_request_handler(http_s *h) {
823
826
  .type = IODINE_HTTP_DEFERRED,
824
827
  };
825
828
 
826
- IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL, &handle);
829
+ IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL,
830
+ &handle);
827
831
 
828
- IodineStore.remove((VALUE)h->fiber);
829
832
  fio_unsubscribe((subscription_s *)h->subscription);
833
+ IodineStore.remove((VALUE)h->fiber);
830
834
 
831
835
  iodine_perform_handle_action(handle);
832
836
  }
@@ -835,9 +839,10 @@ static inline void on_iodine_request_id_message(fio_msg_s *msg) {
835
839
  http_resume((http_pause_handle_s *)msg->udata1, http_resume_deferred_request_handler, NULL);
836
840
  }
837
841
 
842
+ // when Ruby sends a message into the `fiber_id` channel means the fiber attached to
843
+ // to the `http_s h` var can be resumed
838
844
  static inline void http_pause_request_handler(http_pause_handle_s *s) {
839
845
  VALUE fiber_id = rb_funcall((VALUE)s->fiber, fiber_id_method_id, 0);
840
-
841
846
  subscription_s *sub = fio_subscribe(.channel = {0, RSTRING_LEN(fiber_id), RSTRING_PTR(fiber_id)},
842
847
  .on_message = on_iodine_request_id_message,
843
848
  .udata1 = (void *)s);
@@ -845,31 +850,16 @@ static inline void http_pause_request_handler(http_pause_handle_s *s) {
845
850
  s->subscription = (void *)sub;
846
851
  }
847
852
 
848
- static VALUE fiber_request_block(RB_BLOCK_CALL_FUNC_ARGLIST(_, handle_)) {
849
- VALUE fiber_id = rb_funcall(rb_fiber_current(), fiber_id_method_id, 0);
850
-
851
- iodine_http_request_handle_s *handle = (iodine_http_request_handle_s *)handle_;
852
- VALUE rbresponse = (VALUE)IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL, handle);
853
-
854
- fio_publish(.channel = {0, RSTRING_LEN(fiber_id), RSTRING_PTR(fiber_id)});
855
- rb_ivar_set(rb_fiber_current(), fiber_result_var_id, rbresponse);
856
-
857
- return rbresponse;
858
- }
859
-
860
853
  static void on_rack_request(http_s *h) {
861
854
  iodine_http_request_handle_s handle = (iodine_http_request_handle_s){
862
855
  .h = h,
863
856
  .upgrade = IODINE_UPGRADE_NONE,
864
857
  };
858
+ IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL,
859
+ &handle);
865
860
 
866
- VALUE fiber = rb_block_call(rb_cFiber, schedule_method_id, 0, NULL, fiber_request_block, (VALUE)&handle);
867
-
868
- // the fiber encountered blocking IO and yielded - pause the request
869
- if (rb_fiber_alive_p(fiber)) {
870
- IodineStore.add(fiber);
871
- h->fiber = (void *)fiber;
872
- http_pause(h, http_pause_request_handler);
861
+ if (handle.type == IODINE_HTTP_WAIT) {
862
+ http_pause(handle.h, http_pause_request_handler);
873
863
  } else {
874
864
  iodine_perform_handle_action(handle);
875
865
  }
@@ -1037,7 +1027,7 @@ intptr_t iodine_http_listen(iodine_connection_args_s args){
1037
1027
  .on_upgrade = on_rack_upgrade, .udata = (void *)args.handler,
1038
1028
  .timeout = args.timeout, .ws_timeout = args.ping,
1039
1029
  .ws_max_msg_size = args.max_msg, .max_header_size = args.max_headers,
1040
- .on_finish = free_iodine_http, .log = args.log,
1030
+ .on_finish = free_iodine_http, .log = args.log, .max_clients = args.max_clients,
1041
1031
  .max_body_size = args.max_body, .public_folder = args.public.data);
1042
1032
  #else
1043
1033
  intptr_t uuid = http_listen(
@@ -1045,7 +1035,7 @@ intptr_t iodine_http_listen(iodine_connection_args_s args){
1045
1035
  .on_upgrade = on_rack_upgrade, .udata = (void *)args.handler,
1046
1036
  .tls = args.tls, .timeout = args.timeout, .ws_timeout = args.ping,
1047
1037
  .ws_max_msg_size = args.max_msg, .max_header_size = args.max_headers,
1048
- .on_finish = free_iodine_http, .log = args.log,
1038
+ .on_finish = free_iodine_http, .log = args.log, .max_clients = args.max_clients,
1049
1039
  .max_body_size = args.max_body, .public_folder = args.public.data);
1050
1040
  #endif
1051
1041
  if (uuid == -1)
@@ -1249,9 +1239,8 @@ void iodine_init_http(void) {
1249
1239
  attach_method_id = rb_intern("attach_fd");
1250
1240
  iodine_call_proc_id = rb_intern("call");
1251
1241
  fiber_result_var_id = rb_intern("@__result");
1242
+ http_wait_directive = ID2SYM(rb_intern("__http_defer__"));
1252
1243
  fiber_id_method_id = rb_intern("__get_id");
1253
- rb_cFiber = rb_const_get(rb_cObject, rb_intern("Fiber"));
1254
- schedule_method_id = rb_intern("schedule");
1255
1244
 
1256
1245
  IodineUTF8Encoding = rb_enc_find("UTF-8");
1257
1246
  IodineBinaryEncoding = rb_enc_find("binary");
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '3.0.0'.freeze
2
+ VERSION = '3.0.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rage-iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-09 00:00:00.000000000 Z
11
+ date: 2023-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake