rage-iodine 3.0.0 → 3.0.1

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