rage-iodine 3.0.0 → 3.0.1

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: 76bd41c95f58dc8b78c6a748264393b3f7a1410ce348e5e2ebd6ac9b92cd5d75
4
+ data.tar.gz: 9c3518807c7a919eece0fa0d83cdcf9556b3a6f97ff36dea44a365f7d8817b64
5
5
  SHA512:
6
- metadata.gz: 2b8d6ed6f9372e1cbfdd089de2e6d9941e2ef20da98ac5f47e603bcd5369ea4afb51b89fb7e80e01869f4752a8679bcf094d60f3a29930641c98fabe2c3481d9
7
- data.tar.gz: 39f880d839140587dde14e5e1fa3b68bdbb0e35db97333de28a0d024d9d3c8b18cb3575098baeaa813cfc8eb03b459e3042bf6a70aeeec5f57b60557eafddb38
6
+ metadata.gz: 9bab33c03cf6d8f84bc464170e521a344ff3e3af5f3decd303a0d38ff74e0629cf3478b297aa71e4fed41654d00758144ee3824edc7a17745106c4597ba5938b
7
+ data.tar.gz: 38ba3c1a7b8e19f12f11b924c1e94a8feb1e59b0d99fe0050d98d1291aa41f9dcbe6b79dc83521511a8690f975c0b1a0c0aff14d8ae2e752ae862f9013491425
data/CHANGELOG.md CHANGED
@@ -6,9 +6,14 @@ 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.1 (2023-12-11)
10
+
11
+ **Fix**: Disable scheduling request fibers.
12
+
9
13
  #### Change log v.3.0.0 (2023-12-09)
10
14
 
11
15
  **Update**: Schedule request fibers.
16
+ **Update**: Improve stability and memory management under high load.
12
17
 
13
18
  #### Change log v.2.3.0 (2023-11-27)
14
19
 
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
 
@@ -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,14 @@ 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
+ static inline void http_close_deferred_request_handler(void *sub) {
843
+ fio_unsubscribe((subscription_s *)sub);
844
+ }
845
+
846
+ // when Ruby sends a message into the `fiber_id` channel means the fiber attached to
847
+ // to the `http_s h` var can be resumed
838
848
  static inline void http_pause_request_handler(http_pause_handle_s *s) {
839
849
  VALUE fiber_id = rb_funcall((VALUE)s->fiber, fiber_id_method_id, 0);
840
-
841
850
  subscription_s *sub = fio_subscribe(.channel = {0, RSTRING_LEN(fiber_id), RSTRING_PTR(fiber_id)},
842
851
  .on_message = on_iodine_request_id_message,
843
852
  .udata1 = (void *)s);
@@ -845,31 +854,16 @@ static inline void http_pause_request_handler(http_pause_handle_s *s) {
845
854
  s->subscription = (void *)sub;
846
855
  }
847
856
 
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
857
  static void on_rack_request(http_s *h) {
861
858
  iodine_http_request_handle_s handle = (iodine_http_request_handle_s){
862
859
  .h = h,
863
860
  .upgrade = IODINE_UPGRADE_NONE,
864
861
  };
862
+ IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL,
863
+ &handle);
865
864
 
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);
865
+ if (handle.type == IODINE_HTTP_WAIT) {
866
+ http_pause(handle.h, http_pause_request_handler);
873
867
  } else {
874
868
  iodine_perform_handle_action(handle);
875
869
  }
@@ -1249,9 +1243,8 @@ void iodine_init_http(void) {
1249
1243
  attach_method_id = rb_intern("attach_fd");
1250
1244
  iodine_call_proc_id = rb_intern("call");
1251
1245
  fiber_result_var_id = rb_intern("@__result");
1246
+ http_wait_directive = ID2SYM(rb_intern("__http_defer__"));
1252
1247
  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
1248
 
1256
1249
  IodineUTF8Encoding = rb_enc_find("UTF-8");
1257
1250
  IodineBinaryEncoding = rb_enc_find("binary");
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '3.0.0'.freeze
2
+ VERSION = '3.0.1'.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.1
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-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake