rage-iodine 2.3.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/ext/iodine/http.c +4 -0
- data/ext/iodine/http.h +4 -5
- data/ext/iodine/http_internal.h +2 -7
- data/ext/iodine/iodine_http.c +28 -54
- data/lib/iodine/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76bd41c95f58dc8b78c6a748264393b3f7a1410ce348e5e2ebd6ac9b92cd5d75
|
4
|
+
data.tar.gz: 9c3518807c7a919eece0fa0d83cdcf9556b3a6f97ff36dea44a365f7d8817b64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bab33c03cf6d8f84bc464170e521a344ff3e3af5f3decd303a0d38ff74e0629cf3478b297aa71e4fed41654d00758144ee3824edc7a17745106c4597ba5938b
|
7
|
+
data.tar.gz: 38ba3c1a7b8e19f12f11b924c1e94a8feb1e59b0d99fe0050d98d1291aa41f9dcbe6b79dc83521511a8690f975c0b1a0c0aff14d8ae2e752ae862f9013491425
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,47 @@ 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
|
+
|
13
|
+
#### Change log v.3.0.0 (2023-12-09)
|
14
|
+
|
15
|
+
**Update**: Schedule request fibers.
|
16
|
+
**Update**: Improve stability and memory management under high load.
|
17
|
+
|
18
|
+
#### Change log v.2.3.0 (2023-11-27)
|
19
|
+
|
20
|
+
**Fix**: Correctly handle non-persistent HTTP connections.
|
21
|
+
|
22
|
+
#### Change log v.2.2.0 (2023-11-20)
|
23
|
+
|
24
|
+
**Update**: Add `gen_request_tag` and `gen_timestamp` methods.
|
25
|
+
|
26
|
+
**Fix**: Use separate buffer for writing.
|
27
|
+
|
28
|
+
#### Change log v.2.1.1 (2023-11-09)
|
29
|
+
|
30
|
+
**Fix**: Correctly update the fulfilled flag.
|
31
|
+
|
32
|
+
**Fix**: Always send a response.
|
33
|
+
|
34
|
+
#### Change log v.2.1.0 (2023-11-03)
|
35
|
+
|
36
|
+
**Fix**: Return an error on timeouts.
|
37
|
+
|
38
|
+
#### Change log v.2.0.0 (2023-10-31)
|
39
|
+
|
40
|
+
**Update**: Parse params.
|
41
|
+
|
42
|
+
#### Change log v.1.8.0 (2023-09-25)
|
43
|
+
|
44
|
+
**Fix**: Free up memory when closing the protocol.
|
45
|
+
|
46
|
+
#### Change log v.1.7.58 (2023-09-15)
|
47
|
+
|
48
|
+
**Update**: Allow to pause and resume fiber requests.
|
49
|
+
|
9
50
|
#### Change log v.0.7.57 (2023-09-04)
|
10
51
|
|
11
52
|
**Fix**: Fixes possible name collision when loading gem (`.rb` vs. `.so` loading). Credit to @noraj (Alexandre ZANNI) for opening issue #148. Credit to @janbiedermann (Jan Biedermann) for discovering the root cause and offering a solution.
|
data/ext/iodine/http.c
CHANGED
@@ -737,6 +737,8 @@ static void http_resume_wrapper(intptr_t uuid, fio_protocol_s *p_, void *arg) {
|
|
737
737
|
http_pause_handle_s *http = arg;
|
738
738
|
http_s *h = http->h;
|
739
739
|
h->udata = http->udata;
|
740
|
+
h->fiber = http->fiber;
|
741
|
+
h->subscription = http->subscription;
|
740
742
|
http_vtable_s *vtbl = (http_vtable_s *)h->private_data.vtbl;
|
741
743
|
if (http->task)
|
742
744
|
http->task(h);
|
@@ -769,6 +771,8 @@ void http_pause(http_s *h, void (*task)(http_pause_handle_s *http)) {
|
|
769
771
|
.uuid = p->uuid,
|
770
772
|
.h = h,
|
771
773
|
.udata = h->udata,
|
774
|
+
.fiber = h->fiber,
|
775
|
+
.subscription = h->subscription,
|
772
776
|
};
|
773
777
|
vtbl->http_on_pause(h, p);
|
774
778
|
fio_defer(http_pause_wrapper, http, (void *)((uintptr_t)task));
|
data/ext/iodine/http.h
CHANGED
@@ -128,11 +128,8 @@ typedef struct {
|
|
128
128
|
/** in case the request was paused, this will hold a Ruby fiber, that was scheduled during the request. */
|
129
129
|
void *fiber;
|
130
130
|
|
131
|
-
/**
|
132
|
-
|
133
|
-
* once Ruby finishes processing, it will publish to this channel telling Iodine the request can be resumed.
|
134
|
-
*/
|
135
|
-
FIOBJ request_id;
|
131
|
+
/** in case the request needs to be paused, Iodine will subscribe to a channel identified by this object. */
|
132
|
+
void *subscription;
|
136
133
|
} http_s;
|
137
134
|
|
138
135
|
/**
|
@@ -283,6 +280,8 @@ struct http_pause_handle_s {
|
|
283
280
|
uintptr_t uuid;
|
284
281
|
http_s *h;
|
285
282
|
void *udata;
|
283
|
+
void *fiber;
|
284
|
+
void *subscription;
|
286
285
|
void (*task)(http_s *);
|
287
286
|
void (*fallback)(void *);
|
288
287
|
};
|
data/ext/iodine/http_internal.h
CHANGED
@@ -97,10 +97,6 @@ HTTP request/response object management
|
|
97
97
|
|
98
98
|
static inline void http_s_new(http_s *h, http_fio_protocol_s *owner,
|
99
99
|
http_vtable_s *vtbl) {
|
100
|
-
FIOBJ request_id = fiobj_str_buf(14);
|
101
|
-
fiobj_str_write(request_id, "req:", 4);
|
102
|
-
fiobj_str_write_i(request_id, (uint32_t)fio_rand64());
|
103
|
-
|
104
100
|
*h = (http_s){
|
105
101
|
.private_data =
|
106
102
|
{
|
@@ -111,7 +107,6 @@ static inline void http_s_new(http_s *h, http_fio_protocol_s *owner,
|
|
111
107
|
.headers = fiobj_hash_new(),
|
112
108
|
.received_at = fio_last_tick(),
|
113
109
|
.status = 200,
|
114
|
-
.request_id = request_id,
|
115
110
|
};
|
116
111
|
}
|
117
112
|
|
@@ -129,9 +124,9 @@ static inline void http_s_destroy(http_s *h, uint8_t log) {
|
|
129
124
|
fiobj_free(h->cookies);
|
130
125
|
fiobj_free(h->body);
|
131
126
|
fiobj_free(h->params);
|
132
|
-
fiobj_free(h->request_id);
|
133
127
|
|
134
|
-
|
128
|
+
h->fiber = NULL;
|
129
|
+
h->subscription = NULL;
|
135
130
|
|
136
131
|
*h = (http_s){
|
137
132
|
.private_data.vtbl = h->private_data.vtbl,
|
data/ext/iodine/iodine_http.c
CHANGED
@@ -61,6 +61,7 @@ static ID attach_method_id;
|
|
61
61
|
static ID iodine_call_proc_id;
|
62
62
|
static ID fiber_result_var_id;
|
63
63
|
static VALUE http_wait_directive;
|
64
|
+
static ID fiber_id_method_id;
|
64
65
|
|
65
66
|
static VALUE env_template_no_upgrade;
|
66
67
|
static VALUE env_template_websockets;
|
@@ -119,6 +120,7 @@ typedef struct {
|
|
119
120
|
IODINE_HTTP_EMPTY,
|
120
121
|
IODINE_HTTP_ERROR,
|
121
122
|
IODINE_HTTP_WAIT,
|
123
|
+
IODINE_HTTP_DEFERRED,
|
122
124
|
} type;
|
123
125
|
enum iodine_upgrade_type_enum {
|
124
126
|
IODINE_UPGRADE_NONE = 0,
|
@@ -470,9 +472,6 @@ static inline VALUE copy2env(iodine_http_request_handle_s *handle) {
|
|
470
472
|
/* no TLS, no forwarding, assume `http`, which is the default */
|
471
473
|
}
|
472
474
|
}
|
473
|
-
{
|
474
|
-
rb_hash_aset(env, IODINE_REQUEST_ID, rb_str_new_cstr(fiobj_obj2cstr(handle->h->request_id).data));
|
475
|
-
}
|
476
475
|
|
477
476
|
/* add all remaining headers */
|
478
477
|
fiobj_each1(h->headers, 0, iodine_copy2env_task, (void *)env);
|
@@ -674,20 +673,24 @@ Handling HTTP requests
|
|
674
673
|
static inline void *iodine_handle_request_in_GVL(void *handle_) {
|
675
674
|
iodine_http_request_handle_s *handle = handle_;
|
676
675
|
VALUE rbresponse = 0;
|
677
|
-
VALUE env = 0;
|
676
|
+
VALUE env = 0, tmp;
|
678
677
|
http_s *h = handle->h;
|
679
678
|
if (!h->udata)
|
680
679
|
goto err_not_found;
|
681
680
|
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
681
|
+
if (handle->type == IODINE_HTTP_DEFERRED) {
|
682
|
+
rbresponse = rb_ivar_get((VALUE)h->fiber, fiber_result_var_id);
|
683
|
+
} else {
|
684
|
+
// create / register env variable
|
685
|
+
env = copy2env(handle);
|
686
|
+
// create rack.io
|
687
|
+
tmp = IodineRackIO.create(h, env);
|
688
|
+
// pass env variable to handler
|
689
|
+
rbresponse = IodineCaller.call2((VALUE)h->udata, iodine_call_proc_id, 1, &env);
|
690
|
+
// close rack.io
|
691
|
+
IodineRackIO.close(tmp);
|
692
|
+
}
|
693
|
+
|
691
694
|
// test handler's return value
|
692
695
|
if (rbresponse == 0 || rbresponse == Qnil || TYPE(rbresponse) != T_ARRAY) {
|
693
696
|
goto internal_error;
|
@@ -739,7 +742,7 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
|
|
739
742
|
// review each header and write it to the response.
|
740
743
|
rb_hash_foreach(response_headers, for_each_header_data, (VALUE)(h));
|
741
744
|
// review for upgrade.
|
742
|
-
if ((intptr_t)h->status < 300 &&
|
745
|
+
if (handle->type != IODINE_HTTP_DEFERRED && (intptr_t)h->status < 300 &&
|
743
746
|
ruby2c_review_upgrade(handle, rbresponse, env))
|
744
747
|
goto external_done;
|
745
748
|
// send the request body.
|
@@ -777,42 +780,6 @@ defer:
|
|
777
780
|
return NULL;
|
778
781
|
}
|
779
782
|
|
780
|
-
// called once a request that was paused previously needs to be resumed
|
781
|
-
static inline void *iodine_handle_deferred_request_in_GVL(void *handle_) {
|
782
|
-
iodine_http_request_handle_s *handle = handle_;
|
783
|
-
http_s *h = handle->h;
|
784
|
-
|
785
|
-
VALUE rbresponse = rb_ivar_get((VALUE)h->fiber, fiber_result_var_id);
|
786
|
-
VALUE tmp = rb_ary_entry(rbresponse, 0);
|
787
|
-
|
788
|
-
// set response status
|
789
|
-
if (TYPE(tmp) == T_STRING) {
|
790
|
-
char *data = RSTRING_PTR(tmp);
|
791
|
-
h->status = fio_atol(&data);
|
792
|
-
} else if (TYPE(tmp) == T_FIXNUM) {
|
793
|
-
h->status = FIX2ULONG(tmp);
|
794
|
-
} else {
|
795
|
-
goto internal_error;
|
796
|
-
}
|
797
|
-
|
798
|
-
// handle header copy from ruby land to C land.
|
799
|
-
VALUE response_headers = rb_ary_entry(rbresponse, 1);
|
800
|
-
|
801
|
-
// review each header and write it to the response.
|
802
|
-
rb_hash_foreach(response_headers, for_each_header_data, (VALUE)(h));
|
803
|
-
|
804
|
-
// send the request body.
|
805
|
-
if (ruby2c_response_send(handle, rbresponse, 0))
|
806
|
-
goto internal_error;
|
807
|
-
|
808
|
-
return NULL;
|
809
|
-
|
810
|
-
internal_error:
|
811
|
-
h->status = 500;
|
812
|
-
handle->type = IODINE_HTTP_ERROR;
|
813
|
-
return NULL;
|
814
|
-
}
|
815
|
-
|
816
783
|
static inline void
|
817
784
|
iodine_perform_handle_action(iodine_http_request_handle_s handle) {
|
818
785
|
switch (handle.type) {
|
@@ -856,11 +823,15 @@ static inline void http_resume_deferred_request_handler(http_s *h) {
|
|
856
823
|
iodine_http_request_handle_s handle = (iodine_http_request_handle_s){
|
857
824
|
.h = h,
|
858
825
|
.upgrade = IODINE_UPGRADE_NONE,
|
826
|
+
.type = IODINE_HTTP_DEFERRED,
|
859
827
|
};
|
860
828
|
|
861
|
-
IodineCaller.enterGVL((void *(*)(void *))
|
829
|
+
IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL,
|
862
830
|
&handle);
|
863
831
|
|
832
|
+
fio_unsubscribe((subscription_s *)h->subscription);
|
833
|
+
IodineStore.remove((VALUE)h->fiber);
|
834
|
+
|
864
835
|
iodine_perform_handle_action(handle);
|
865
836
|
}
|
866
837
|
|
@@ -872,13 +843,15 @@ static inline void http_close_deferred_request_handler(void *sub) {
|
|
872
843
|
fio_unsubscribe((subscription_s *)sub);
|
873
844
|
}
|
874
845
|
|
875
|
-
// when Ruby sends a message into the `
|
846
|
+
// when Ruby sends a message into the `fiber_id` channel means the fiber attached to
|
876
847
|
// to the `http_s h` var can be resumed
|
877
848
|
static inline void http_pause_request_handler(http_pause_handle_s *s) {
|
878
|
-
|
849
|
+
VALUE fiber_id = rb_funcall((VALUE)s->fiber, fiber_id_method_id, 0);
|
850
|
+
subscription_s *sub = fio_subscribe(.channel = {0, RSTRING_LEN(fiber_id), RSTRING_PTR(fiber_id)},
|
879
851
|
.on_message = on_iodine_request_id_message,
|
880
852
|
.udata1 = (void *)s);
|
881
|
-
|
853
|
+
|
854
|
+
s->subscription = (void *)sub;
|
882
855
|
}
|
883
856
|
|
884
857
|
static void on_rack_request(http_s *h) {
|
@@ -1271,6 +1244,7 @@ void iodine_init_http(void) {
|
|
1271
1244
|
iodine_call_proc_id = rb_intern("call");
|
1272
1245
|
fiber_result_var_id = rb_intern("@__result");
|
1273
1246
|
http_wait_directive = ID2SYM(rb_intern("__http_defer__"));
|
1247
|
+
fiber_id_method_id = rb_intern("__get_id");
|
1274
1248
|
|
1275
1249
|
IodineUTF8Encoding = rb_enc_find("UTF-8");
|
1276
1250
|
IodineBinaryEncoding = rb_enc_find("binary");
|
data/lib/iodine/version.rb
CHANGED
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:
|
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-11
|
11
|
+
date: 2023-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|