rage-iodine 3.0.0 → 3.0.2

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