iodine 0.7.20 → 0.7.21
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/examples/shootout.ru +1 -1
- data/ext/iodine/fio.c +57 -35
- data/ext/iodine/fio.h +10 -3
- data/ext/iodine/http1.c +9 -5
- data/ext/iodine/iodine_fiobj2rb.h +1 -1
- data/ext/iodine/iodine_json.c +1 -0
- data/ext/iodine/iodine_pubsub.c +22 -9
- data/ext/iodine/redis_engine.c +47 -29
- data/lib/iodine/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0f9360224da57145ba3ed9e81d5e5472cf9bb9732c9d36fab6e22c32428013a
|
4
|
+
data.tar.gz: e04fc9d016bbb53cf80d810765a5b934d0d996d447faadd6451c27612cd17da6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 970307f1349dd8ca00a6caa6bfb59c6485f05fdb0b1654dd2788f3b477f628aa9b1c24a9df0873409930dd071dc446e999164731892fe7d70a64983f49a72d99
|
7
|
+
data.tar.gz: aa2417372b97f415ee83edd7aa0ecd557cef4144eba546cd931bc36078574cc03b574f16a395a779957015084c1737b996d13337516ac474efa78d4140075035
|
data/CHANGELOG.md
CHANGED
@@ -6,9 +6,17 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
6
6
|
|
7
7
|
## Changes:
|
8
8
|
|
9
|
+
#### Change log v.0.7.21
|
10
|
+
|
11
|
+
**Fix**: (`iodine`, `redis`) Redis response was attempting to create Ruby objects outside the GIL. This is now fixed by entering the GIL earlier (before objects are created). Credit to @moxgeek (Marouane Elmidaoui) for exposing this issue (plezi#31).
|
12
|
+
|
13
|
+
**Fix**: (`redis`) fixed Redis reconnection. Address and port data was mistakingly written at the wrong address, causing it to be overwritten by incoming (non-pub/sub) data.
|
14
|
+
|
15
|
+
**Fix**: (`redis`) fixed a race condition in the Redis reconnection logic which might have caused more then a single pub/sub connection to be established and the first pending command to be sent again.
|
16
|
+
|
9
17
|
#### Change log v.0.7.20
|
10
18
|
|
11
|
-
**Security**: (`fio`) lower Slowloris detection limits (backlog limit is now 1,024 responses / messages per client).
|
19
|
+
**Security**: (`fio`) lower and smarter Slowloris detection limits (backlog limit is now 1,024 responses / messages per client).
|
12
20
|
|
13
21
|
**Security**: (`http`) HTTP/1.1 slow client throttling - new requests will not be consumed until pending responses were sent. Since HTTP/1.1 is a response-request protocol, this protocol specific approach should protect the HTTP application against slow clients.
|
14
22
|
|
data/examples/shootout.ru
CHANGED
data/ext/iodine/fio.c
CHANGED
@@ -2901,42 +2901,32 @@ void fio_force_close(intptr_t uuid) {
|
|
2901
2901
|
* error or when the connection is closed.
|
2902
2902
|
*/
|
2903
2903
|
ssize_t fio_flush(intptr_t uuid) {
|
2904
|
-
if (!uuid_is_valid(uuid))
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2908
|
-
ssize_t flushed;
|
2904
|
+
if (!uuid_is_valid(uuid))
|
2905
|
+
goto invalid;
|
2906
|
+
errno = 0;
|
2907
|
+
ssize_t flushed = 0;
|
2909
2908
|
int tmp;
|
2910
2909
|
/* start critical section */
|
2911
2910
|
if (fio_trylock(&uuid_data(uuid).sock_lock))
|
2912
2911
|
goto would_block;
|
2913
2912
|
|
2914
|
-
if (uuid_data(uuid).packet)
|
2915
|
-
|
2916
|
-
uuid_data(uuid).packet);
|
2917
|
-
const size_t old_count = uuid_data(uuid).packet_count;
|
2918
|
-
if (tmp == 0) {
|
2919
|
-
errno = ECONNRESET;
|
2920
|
-
fio_unlock(&uuid_data(uuid).sock_lock);
|
2921
|
-
uuid_data(uuid).close = 1;
|
2922
|
-
goto closed;
|
2923
|
-
} else if (tmp < 0) {
|
2924
|
-
goto test_errno;
|
2925
|
-
}
|
2913
|
+
if (!uuid_data(uuid).packet)
|
2914
|
+
goto flush_rw_hook;
|
2926
2915
|
|
2927
|
-
|
2928
|
-
|
2929
|
-
goto attacked;
|
2930
|
-
}
|
2916
|
+
const size_t old_count = uuid_data(uuid).packet_count;
|
2917
|
+
const size_t old_sent = uuid_data(uuid).sent;
|
2931
2918
|
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
2936
|
-
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2919
|
+
tmp = uuid_data(uuid).packet->write_func(fio_uuid2fd(uuid),
|
2920
|
+
uuid_data(uuid).packet);
|
2921
|
+
if (tmp <= 0) {
|
2922
|
+
goto test_errno;
|
2923
|
+
}
|
2924
|
+
|
2925
|
+
if (old_count >= 1024 && uuid_data(uuid).packet_count == old_count &&
|
2926
|
+
uuid_data(uuid).sent >= old_sent &&
|
2927
|
+
(uuid_data(uuid).sent - old_sent) < 32768) {
|
2928
|
+
/* Slowloris attack assumed */
|
2929
|
+
goto attacked;
|
2940
2930
|
}
|
2941
2931
|
|
2942
2932
|
/* end critical section */
|
@@ -2952,22 +2942,48 @@ ssize_t fio_flush(intptr_t uuid) {
|
|
2952
2942
|
would_block:
|
2953
2943
|
errno = EWOULDBLOCK;
|
2954
2944
|
return -1;
|
2945
|
+
|
2955
2946
|
closed:
|
2956
2947
|
fio_force_close(uuid);
|
2957
2948
|
return -1;
|
2949
|
+
|
2950
|
+
flush_rw_hook:
|
2951
|
+
flushed = uuid_data(uuid).rw_hooks->flush(uuid, uuid_data(uuid).rw_udata);
|
2952
|
+
fio_unlock(&uuid_data(uuid).sock_lock);
|
2953
|
+
if (!flushed)
|
2954
|
+
return 0;
|
2955
|
+
if (flushed < 0) {
|
2956
|
+
goto test_errno;
|
2957
|
+
}
|
2958
|
+
touchfd(fio_uuid2fd(uuid));
|
2959
|
+
return 1;
|
2960
|
+
|
2958
2961
|
test_errno:
|
2959
2962
|
fio_unlock(&uuid_data(uuid).sock_lock);
|
2960
|
-
|
2961
|
-
|
2963
|
+
switch (errno) {
|
2964
|
+
case EWOULDBLOCK: /* ovreflow */
|
2965
|
+
#if EWOULDBLOCK != EAGAIN
|
2966
|
+
case EAGAIN: /* ovreflow */
|
2967
|
+
#endif
|
2968
|
+
case ENOTCONN: /* ovreflow */
|
2969
|
+
case EINPROGRESS: /* ovreflow */
|
2970
|
+
case ENOSPC: /* ovreflow */
|
2971
|
+
case EINTR:
|
2962
2972
|
return 1;
|
2973
|
+
case EPIPE: /* ovreflow */
|
2974
|
+
case EIO: /* ovreflow */
|
2975
|
+
case EINVAL: /* ovreflow */
|
2976
|
+
case EBADF:
|
2977
|
+
uuid_data(uuid).close = 1;
|
2978
|
+
fio_force_close(uuid);
|
2979
|
+
return -1;
|
2963
2980
|
}
|
2964
2981
|
return 0;
|
2965
2982
|
|
2983
|
+
invalid:
|
2984
|
+
/* bad UUID */
|
2985
|
+
errno = EBADF;
|
2966
2986
|
return -1;
|
2967
|
-
flushed:
|
2968
|
-
touchfd(fio_uuid2fd(uuid));
|
2969
|
-
fio_unlock(&uuid_data(uuid).sock_lock);
|
2970
|
-
return 1;
|
2971
2987
|
|
2972
2988
|
attacked:
|
2973
2989
|
/* don't close, just detach from facil.io and mark uuid as invalid */
|
@@ -6508,6 +6524,8 @@ static inline void fio_publish2process2(int32_t filter, fio_str_info_s ch_name,
|
|
6508
6524
|
fio_pubsub_create_message(filter, ch_name, msg, is_json, 1));
|
6509
6525
|
}
|
6510
6526
|
|
6527
|
+
/* Sublime Text marker */
|
6528
|
+
void fio_publish___(fio_publish_args_s args);
|
6511
6529
|
/**
|
6512
6530
|
* Publishes a message to the relevant subscribers (if any).
|
6513
6531
|
*
|
@@ -8763,6 +8781,8 @@ FIO_FUNC inline void fio_llist_test(void) {
|
|
8763
8781
|
FIO_ASSERT_ALLOC(n);
|
8764
8782
|
n->i = i;
|
8765
8783
|
fio_ls_embd_push(&emlist, &n->node);
|
8784
|
+
FIO_ASSERT(FIO_LS_EMBD_OBJ(struct fio_ls_test_s, node, emlist.next)->i == 0,
|
8785
|
+
"fio_ls_embd_push should push to the end.");
|
8766
8786
|
}
|
8767
8787
|
FIO_ASSERT(fio_ls_embd_any(&emlist),
|
8768
8788
|
"List should be populated after fio_ls_embd_push");
|
@@ -8794,6 +8814,8 @@ FIO_FUNC inline void fio_llist_test(void) {
|
|
8794
8814
|
FIO_ASSERT_ALLOC(n)
|
8795
8815
|
n->i = i;
|
8796
8816
|
fio_ls_embd_unshift(&emlist, &n->node);
|
8817
|
+
FIO_ASSERT(FIO_LS_EMBD_OBJ(struct fio_ls_test_s, node, emlist.next)->i == i,
|
8818
|
+
"fio_ls_embd_unshift should push to the start.");
|
8797
8819
|
}
|
8798
8820
|
FIO_ASSERT(fio_ls_embd_any(&emlist),
|
8799
8821
|
"List should be populated after fio_ls_embd_unshift");
|
data/ext/iodine/fio.h
CHANGED
@@ -427,9 +427,16 @@ int __attribute__((weak)) FIO_LOG_LEVEL;
|
|
427
427
|
int len___log = \
|
428
428
|
snprintf(tmp___log, FIO_LOG_LENGTH_LIMIT - 2, __VA_ARGS__); \
|
429
429
|
if (len___log <= 0 || len___log >= FIO_LOG_LENGTH_LIMIT - 2) { \
|
430
|
-
|
431
|
-
|
432
|
-
|
430
|
+
if (len___log >= (FIO_LOG_LENGTH_LIMIT >> 2) && \
|
431
|
+
(FIO_LOG_LENGTH_LIMIT >> 2) + 52 < FIO_LOG_LENGTH_LIMIT) { \
|
432
|
+
fwrite(tmp___log, (FIO_LOG_LENGTH_LIMIT >> 2), 1, stderr); \
|
433
|
+
memcpy(tmp___log + (FIO_LOG_LENGTH_LIMIT >> 2), \
|
434
|
+
"...\nERROR: log line output too long (can't write).\n", 52); \
|
435
|
+
len___log = (FIO_LOG_LENGTH_LIMIT >> 2) + 52; \
|
436
|
+
} else { \
|
437
|
+
fwrite("ERROR: log output error (can't write).\n", 39, 1, stderr); \
|
438
|
+
break; \
|
439
|
+
} \
|
433
440
|
} \
|
434
441
|
tmp___log[len___log++] = '\n'; \
|
435
442
|
tmp___log[len___log] = '0'; \
|
data/ext/iodine/http1.c
CHANGED
@@ -676,11 +676,8 @@ Connection Callbacks
|
|
676
676
|
***************************************************************************** */
|
677
677
|
|
678
678
|
static inline void http1_consume_data(intptr_t uuid, http1pr_s *p) {
|
679
|
-
if (fio_pending(uuid) > 4) {
|
680
|
-
|
681
|
-
FIO_LOG_DEBUG("(HTTP/1,1) throttling client at %.*s",
|
682
|
-
(int)fio_peer_addr(uuid).len, fio_peer_addr(uuid).data);
|
683
|
-
return;
|
679
|
+
if (fio_pending(uuid) > 4) {
|
680
|
+
goto throttle;
|
684
681
|
}
|
685
682
|
ssize_t i = 0;
|
686
683
|
size_t org_len = p->buf_len;
|
@@ -720,6 +717,13 @@ static inline void http1_consume_data(intptr_t uuid, http1pr_s *p) {
|
|
720
717
|
if (!pipeline_limit) {
|
721
718
|
fio_force_event(uuid, FIO_EVENT_ON_DATA);
|
722
719
|
}
|
720
|
+
return;
|
721
|
+
|
722
|
+
throttle:
|
723
|
+
/* throttle busy clients (slowloris) */
|
724
|
+
fio_suspend(uuid);
|
725
|
+
FIO_LOG_DEBUG("(HTTP/1,1) throttling client at %.*s",
|
726
|
+
(int)fio_peer_addr(uuid).len, fio_peer_addr(uuid).data);
|
723
727
|
}
|
724
728
|
|
725
729
|
/** called when a data is available, but will not run concurrently */
|
@@ -110,7 +110,7 @@ static inline VALUE fiobj2rb_deep(FIOBJ obj, uint8_t str2sym) {
|
|
110
110
|
while (fiobj_ary_pop(data.stack))
|
111
111
|
;
|
112
112
|
fiobj_free(data.stack);
|
113
|
-
IodineStore.remove(data.rb);
|
113
|
+
// IodineStore.remove(data.rb); // don't remove data
|
114
114
|
return data.rb;
|
115
115
|
}
|
116
116
|
|
data/ext/iodine/iodine_json.c
CHANGED
data/ext/iodine/iodine_pubsub.c
CHANGED
@@ -181,6 +181,7 @@ static void iodine_pubsub_data_mark(void *c_) {
|
|
181
181
|
}
|
182
182
|
/* a callback for the GC (marking active objects) */
|
183
183
|
static void iodine_pubsub_data_free(void *c_) {
|
184
|
+
FIO_LOG_DEBUG("iodine destroying engine");
|
184
185
|
iodine_pubsub_s *data = c_;
|
185
186
|
fio_pubsub_detach(data->engine);
|
186
187
|
IodineStore.remove(data->handler); /* redundant except during exit */
|
@@ -411,20 +412,32 @@ static VALUE iodine_pubsub_redis_new(int argc, VALUE *argv, VALUE self) {
|
|
411
412
|
(void)argv;
|
412
413
|
}
|
413
414
|
|
415
|
+
struct redis_callback_data {
|
416
|
+
FIOBJ response;
|
417
|
+
VALUE block;
|
418
|
+
};
|
419
|
+
|
420
|
+
/** A callback for Redis commands. */
|
421
|
+
static void *iodine_pubsub_redis_callback_in_gil(void *data_) {
|
422
|
+
struct redis_callback_data *d = data_;
|
423
|
+
VALUE rb = Qnil;
|
424
|
+
if (!FIOBJ_IS_NULL(d->response)) {
|
425
|
+
rb = fiobj2rb_deep(d->response, 0);
|
426
|
+
}
|
427
|
+
IodineCaller.call2(d->block, call_id, 1, &rb);
|
428
|
+
IodineStore.remove(rb);
|
429
|
+
return NULL;
|
430
|
+
}
|
431
|
+
|
414
432
|
/** A callback for Redis commands. */
|
415
433
|
static void iodine_pubsub_redis_callback(fio_pubsub_engine_s *e, FIOBJ response,
|
416
434
|
void *udata) {
|
417
|
-
|
418
|
-
if (block == Qnil) {
|
435
|
+
struct redis_callback_data d = {.response = response, .block = (VALUE)udata};
|
436
|
+
if (d.block == Qnil) {
|
419
437
|
return;
|
420
438
|
}
|
421
|
-
|
422
|
-
|
423
|
-
rb = IodineStore.add(fiobj2rb_deep(response, 0));
|
424
|
-
}
|
425
|
-
IodineCaller.call2(block, call_id, 1, &rb);
|
426
|
-
IodineStore.remove(rb);
|
427
|
-
IodineStore.remove(block);
|
439
|
+
IodineCaller.enterGVL(iodine_pubsub_redis_callback_in_gil, &d);
|
440
|
+
IodineStore.remove(d.block);
|
428
441
|
(void)e;
|
429
442
|
}
|
430
443
|
|
data/ext/iodine/redis_engine.c
CHANGED
@@ -44,8 +44,9 @@ typedef struct {
|
|
44
44
|
size_t ref;
|
45
45
|
fio_ls_embd_s queue;
|
46
46
|
fio_lock_i lock;
|
47
|
+
fio_lock_i lock_connection;
|
47
48
|
uint8_t ping_int;
|
48
|
-
uint8_t
|
49
|
+
volatile uint8_t pub_sent;
|
49
50
|
volatile uint8_t flag;
|
50
51
|
uint8_t buf[];
|
51
52
|
} redis_engine_s;
|
@@ -84,6 +85,7 @@ static inline void redis_internal_reset(struct redis_engine_internal_s *i) {
|
|
84
85
|
static inline void redis_free(redis_engine_s *r) {
|
85
86
|
if (fio_atomic_sub(&r->ref, 1))
|
86
87
|
return;
|
88
|
+
FIO_LOG_DEBUG("freeing redis engine for %s:%s", r->address, r->port);
|
87
89
|
redis_internal_reset(&r->pub_data);
|
88
90
|
redis_internal_reset(&r->sub_data);
|
89
91
|
fiobj_free(r->last_ch);
|
@@ -310,30 +312,42 @@ static void redis_perform_callback(void *e, void *cmd_) {
|
|
310
312
|
fio_free(cmd);
|
311
313
|
}
|
312
314
|
|
315
|
+
/* send command within lock, to ensure flag integrity */
|
316
|
+
static void redis_send_next_command_unsafe(redis_engine_s *r) {
|
317
|
+
if (!r->pub_sent && fio_ls_embd_any(&r->queue)) {
|
318
|
+
r->pub_sent = 1;
|
319
|
+
redis_commands_s *cmd =
|
320
|
+
FIO_LS_EMBD_OBJ(redis_commands_s, node, r->queue.next);
|
321
|
+
fio_write2(r->pub_data.uuid, .data.buffer = cmd->cmd,
|
322
|
+
.length = cmd->cmd_len, .after.dealloc = FIO_DEALLOC_NOOP);
|
323
|
+
FIO_LOG_DEBUG("(redis %d) Sending (%zu bytes):\n%s\n", getpid(),
|
324
|
+
cmd->cmd_len, cmd->cmd);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
313
328
|
/* attach a command to the queue */
|
314
329
|
static void redis_attach_cmd(redis_engine_s *r, redis_commands_s *cmd) {
|
315
330
|
fio_lock(&r->lock);
|
316
331
|
fio_ls_embd_push(&r->queue, &cmd->node);
|
317
|
-
|
318
|
-
fio_write2(r->pub_data.uuid, .data.buffer = cmd->cmd,
|
319
|
-
.length = cmd->cmd_len, .after.dealloc = FIO_DEALLOC_NOOP);
|
320
|
-
FIO_LOG_DEBUG("(%d) Sending (%zu bytes):\n%s\n", getpid(), cmd->cmd_len,
|
321
|
-
cmd->cmd);
|
322
|
-
}
|
332
|
+
redis_send_next_command_unsafe(r);
|
323
333
|
fio_unlock(&r->lock);
|
324
334
|
}
|
325
335
|
|
326
336
|
/** a local static callback, called when the RESP message is complete. */
|
327
337
|
static void resp_on_pub_message(struct redis_engine_internal_s *i, FIOBJ msg) {
|
328
338
|
redis_engine_s *r = pub2redis(i);
|
329
|
-
#if DEBUG
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
339
|
+
// #if DEBUG
|
340
|
+
if (FIO_LOG_LEVEL >= FIO_LOG_LEVEL_DEBUG) {
|
341
|
+
FIOBJ json = fiobj_obj2json(msg, 1);
|
342
|
+
FIO_LOG_DEBUG("Redis reply:\n%s\n", fiobj_obj2cstr(json).data);
|
343
|
+
fiobj_free(json);
|
344
|
+
}
|
345
|
+
// #endif
|
334
346
|
/* publishing / command parser */
|
335
347
|
fio_lock(&r->lock);
|
336
348
|
fio_ls_embd_s *node = fio_ls_embd_shift(&r->queue);
|
349
|
+
r->pub_sent = 0;
|
350
|
+
redis_send_next_command_unsafe(r);
|
337
351
|
fio_unlock(&r->lock);
|
338
352
|
if (!node) {
|
339
353
|
/* TODO: possible ping? from server?! not likely... */
|
@@ -358,8 +372,8 @@ static void resp_on_sub_message(struct redis_engine_internal_s *i, FIOBJ msg) {
|
|
358
372
|
if (FIOBJ_TYPE(msg) != FIOBJ_T_STRING || fiobj_obj2cstr(msg).len != 4 ||
|
359
373
|
fiobj_obj2cstr(msg).data[0] != 'P') {
|
360
374
|
FIO_LOG_WARNING("(redis) unexpected data format in "
|
361
|
-
"subscription stream:\n %s",
|
362
|
-
fiobj_obj2cstr(msg).data);
|
375
|
+
"subscription stream (%zu bytes):\n %s\n",
|
376
|
+
fiobj_obj2cstr(msg).len, fiobj_obj2cstr(msg).data);
|
363
377
|
}
|
364
378
|
} else {
|
365
379
|
// FIOBJ *ary = fiobj_ary2ptr(msg);
|
@@ -410,6 +424,7 @@ static void redis_on_data(intptr_t uuid, fio_protocol_s *pr) {
|
|
410
424
|
REDIS_READ_BUFFER - internal->buf_pos);
|
411
425
|
if (i <= 0)
|
412
426
|
return;
|
427
|
+
|
413
428
|
internal->buf_pos += i;
|
414
429
|
i = resp_parse(&internal->parser, buf, internal->buf_pos);
|
415
430
|
if (i) {
|
@@ -447,7 +462,7 @@ static void redis_on_close(intptr_t uuid, fio_protocol_s *pr) {
|
|
447
462
|
"Reconnecting...",
|
448
463
|
(int)getpid());
|
449
464
|
}
|
450
|
-
r->
|
465
|
+
r->pub_sent = 0;
|
451
466
|
fio_close(r->sub_data.uuid);
|
452
467
|
redis_free(r);
|
453
468
|
}
|
@@ -523,19 +538,16 @@ static void redis_on_connect(intptr_t uuid, void *i_) {
|
|
523
538
|
(redis_commands_s){.cmd_len = r->auth_len, .callback = redis_on_auth};
|
524
539
|
memcpy(cmd->cmd, r->auth, r->auth_len);
|
525
540
|
fio_lock(&r->lock);
|
541
|
+
r->pub_sent = 0;
|
526
542
|
fio_ls_embd_unshift(&r->queue, &cmd->node);
|
543
|
+
redis_send_next_command_unsafe(r);
|
544
|
+
fio_unlock(&r->lock);
|
545
|
+
} else {
|
546
|
+
fio_lock(&r->lock);
|
547
|
+
r->pub_sent = 0;
|
548
|
+
redis_send_next_command_unsafe(r);
|
527
549
|
fio_unlock(&r->lock);
|
528
550
|
}
|
529
|
-
fio_lock(&r->lock);
|
530
|
-
FIO_LS_EMBD_FOR(&r->queue, node) {
|
531
|
-
redis_commands_s *cmd = FIO_LS_EMBD_OBJ(redis_commands_s, node, node);
|
532
|
-
FIO_LOG_DEBUG("(%d) Sending (%zu bytes):\n%s\n", getpid(), cmd->cmd_len,
|
533
|
-
cmd->cmd);
|
534
|
-
fio_write2(uuid, .data.buffer = cmd->cmd, .length = cmd->cmd_len,
|
535
|
-
.after.dealloc = FIO_DEALLOC_NOOP);
|
536
|
-
}
|
537
|
-
r->pub_send = 1;
|
538
|
-
fio_unlock(&r->lock);
|
539
551
|
FIO_LOG_INFO("(redis %d) publication connection established.",
|
540
552
|
(int)getpid());
|
541
553
|
}
|
@@ -557,7 +569,9 @@ static void redis_on_connect_failed(intptr_t uuid, void *i_) {
|
|
557
569
|
static void redis_connect(void *r_, void *i_) {
|
558
570
|
redis_engine_s *r = r_;
|
559
571
|
struct redis_engine_internal_s *i = i_;
|
572
|
+
fio_lock(&r->lock_connection);
|
560
573
|
if (r->flag == 0 || i->uuid != -1 || !fio_is_running()) {
|
574
|
+
fio_unlock(&r->lock_connection);
|
561
575
|
redis_free(r);
|
562
576
|
return;
|
563
577
|
}
|
@@ -565,6 +579,7 @@ static void redis_connect(void *r_, void *i_) {
|
|
565
579
|
i->uuid = fio_connect(.address = r->address, .port = r->port,
|
566
580
|
.on_connect = redis_on_connect, .udata = i,
|
567
581
|
.on_fail = redis_on_connect_failed);
|
582
|
+
fio_unlock(&r->lock_connection);
|
568
583
|
}
|
569
584
|
|
570
585
|
/* *****************************************************************************
|
@@ -714,7 +729,7 @@ static void redis_forward_reply(fio_pubsub_engine_s *e, FIOBJ reply,
|
|
714
729
|
}
|
715
730
|
int32_t pid = (int32_t)fio_str2u32(data + 24);
|
716
731
|
FIOBJ rp = fiobj_obj2json(reply, 0);
|
717
|
-
fio_publish(.filter = (-10 - pid), .channel.data = (char *)data,
|
732
|
+
fio_publish(.filter = (-10 - (int32_t)pid), .channel.data = (char *)data,
|
718
733
|
.channel.len = 28, .message = fiobj_obj2cstr(rp), .is_json = 1);
|
719
734
|
fiobj_free(rp);
|
720
735
|
}
|
@@ -895,13 +910,16 @@ FIO_IGNORE_MACRO(struct redis_engine_create_args args) {
|
|
895
910
|
.cmd_reply =
|
896
911
|
fio_subscribe(.filter = -10 - (uint32_t)getpid(), .udata1 = r,
|
897
912
|
.on_message = redis_on_internal_reply),
|
898
|
-
.address = ((char *)(r + 1) +
|
899
|
-
.port =
|
900
|
-
|
913
|
+
.address = ((char *)(r + 1) + (REDIS_READ_BUFFER * 2)),
|
914
|
+
.port =
|
915
|
+
((char *)(r + 1) + (REDIS_READ_BUFFER * 2) + args.address.len + 1),
|
916
|
+
.auth = ((char *)(r + 1) + (REDIS_READ_BUFFER * 2) + args.address.len +
|
917
|
+
args.port.len + 2),
|
901
918
|
.auth_len = args.auth.len,
|
902
919
|
.ref = 1,
|
903
920
|
.queue = FIO_LS_INIT(r->queue),
|
904
921
|
.lock = FIO_LOCK_INIT,
|
922
|
+
.lock_connection = FIO_LOCK_INIT,
|
905
923
|
.ping_int = args.ping_interval,
|
906
924
|
.flag = 1,
|
907
925
|
};
|
data/lib/iodine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01
|
11
|
+
date: 2019-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -220,7 +220,7 @@ licenses:
|
|
220
220
|
- MIT
|
221
221
|
metadata:
|
222
222
|
allowed_push_host: https://rubygems.org
|
223
|
-
post_install_message: 'Thank you for installing Iodine 0.7.
|
223
|
+
post_install_message: 'Thank you for installing Iodine 0.7.21.
|
224
224
|
|
225
225
|
'
|
226
226
|
rdoc_options: []
|