durable_rules 0.33.13 → 0.34.01
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/deps/hiredis/Makefile +110 -41
- data/deps/hiredis/async.c +87 -22
- data/deps/hiredis/async.h +4 -0
- data/deps/hiredis/fmacros.h +6 -1
- data/deps/hiredis/hiredis.c +270 -534
- data/deps/hiredis/hiredis.h +89 -76
- data/deps/hiredis/net.c +206 -47
- data/deps/hiredis/net.h +12 -6
- data/deps/hiredis/read.c +525 -0
- data/deps/hiredis/read.h +116 -0
- data/deps/hiredis/sds.c +260 -47
- data/deps/hiredis/sds.h +11 -6
- data/deps/hiredis/test.c +171 -18
- data/deps/hiredis/win32.h +42 -0
- data/librb/durable.rb +35 -6
- data/librb/engine.rb +173 -40
- data/src/rules/events.c +42 -4
- data/src/rules/net.c +184 -96
- data/src/rules/net.h +10 -0
- data/src/rules/rules.h +13 -0
- data/src/rulesrb/rules.c +55 -0
- metadata +5 -3
- data/deps/hiredis/zmalloc.h +0 -13
data/deps/hiredis/sds.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/*
|
1
|
+
/* SDS (Simple Dynamic Strings), A C dynamic strings library.
|
2
2
|
*
|
3
|
-
* Copyright (c) 2006-
|
3
|
+
* Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
|
4
4
|
* All rights reserved.
|
5
5
|
*
|
6
6
|
* Redistribution and use in source and binary forms, with or without
|
@@ -35,6 +35,9 @@
|
|
35
35
|
|
36
36
|
#include <sys/types.h>
|
37
37
|
#include <stdarg.h>
|
38
|
+
#ifdef _MSC_VER
|
39
|
+
#include "win32.h"
|
40
|
+
#endif
|
38
41
|
|
39
42
|
typedef char *sds;
|
40
43
|
|
@@ -45,12 +48,12 @@ struct sdshdr {
|
|
45
48
|
};
|
46
49
|
|
47
50
|
static inline size_t sdslen(const sds s) {
|
48
|
-
struct sdshdr *sh = (
|
51
|
+
struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
|
49
52
|
return sh->len;
|
50
53
|
}
|
51
54
|
|
52
55
|
static inline size_t sdsavail(const sds s) {
|
53
|
-
struct sdshdr *sh = (
|
56
|
+
struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
|
54
57
|
return sh->free;
|
55
58
|
}
|
56
59
|
|
@@ -76,7 +79,8 @@ sds sdscatprintf(sds s, const char *fmt, ...)
|
|
76
79
|
sds sdscatprintf(sds s, const char *fmt, ...);
|
77
80
|
#endif
|
78
81
|
|
79
|
-
sds
|
82
|
+
sds sdscatfmt(sds s, char const *fmt, ...);
|
83
|
+
void sdstrim(sds s, const char *cset);
|
80
84
|
void sdsrange(sds s, int start, int end);
|
81
85
|
void sdsupdatelen(sds s);
|
82
86
|
void sdsclear(sds s);
|
@@ -89,7 +93,8 @@ sds sdsfromlonglong(long long value);
|
|
89
93
|
sds sdscatrepr(sds s, const char *p, size_t len);
|
90
94
|
sds *sdssplitargs(const char *line, int *argc);
|
91
95
|
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
|
92
|
-
sds sdsjoin(char **argv, int argc, char *sep);
|
96
|
+
sds sdsjoin(char **argv, int argc, char *sep, size_t seplen);
|
97
|
+
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
|
93
98
|
|
94
99
|
/* Low level functions exposed to the user API */
|
95
100
|
sds sdsMakeRoomFor(sds s, size_t addlen);
|
data/deps/hiredis/test.c
CHANGED
@@ -8,12 +8,15 @@
|
|
8
8
|
#include <unistd.h>
|
9
9
|
#include <signal.h>
|
10
10
|
#include <errno.h>
|
11
|
+
#include <limits.h>
|
11
12
|
|
12
13
|
#include "hiredis.h"
|
14
|
+
#include "net.h"
|
13
15
|
|
14
16
|
enum connection_type {
|
15
17
|
CONN_TCP,
|
16
|
-
CONN_UNIX
|
18
|
+
CONN_UNIX,
|
19
|
+
CONN_FD
|
17
20
|
};
|
18
21
|
|
19
22
|
struct config {
|
@@ -22,6 +25,7 @@ struct config {
|
|
22
25
|
struct {
|
23
26
|
const char *host;
|
24
27
|
int port;
|
28
|
+
struct timeval timeout;
|
25
29
|
} tcp;
|
26
30
|
|
27
31
|
struct {
|
@@ -40,6 +44,13 @@ static long long usec(void) {
|
|
40
44
|
return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
|
41
45
|
}
|
42
46
|
|
47
|
+
/* The assert() calls below have side effects, so we need assert()
|
48
|
+
* even if we are compiling without asserts (-DNDEBUG). */
|
49
|
+
#ifdef NDEBUG
|
50
|
+
#undef assert
|
51
|
+
#define assert(e) (void)(e)
|
52
|
+
#endif
|
53
|
+
|
43
54
|
static redisContext *select_database(redisContext *c) {
|
44
55
|
redisReply *reply;
|
45
56
|
|
@@ -62,7 +73,7 @@ static redisContext *select_database(redisContext *c) {
|
|
62
73
|
return c;
|
63
74
|
}
|
64
75
|
|
65
|
-
static
|
76
|
+
static int disconnect(redisContext *c, int keep_fd) {
|
66
77
|
redisReply *reply;
|
67
78
|
|
68
79
|
/* Make sure we're on DB 9. */
|
@@ -73,8 +84,11 @@ static void disconnect(redisContext *c) {
|
|
73
84
|
assert(reply != NULL);
|
74
85
|
freeReplyObject(reply);
|
75
86
|
|
76
|
-
/* Free the context as well. */
|
87
|
+
/* Free the context as well, but keep the fd if requested. */
|
88
|
+
if (keep_fd)
|
89
|
+
return redisFreeKeepFd(c);
|
77
90
|
redisFree(c);
|
91
|
+
return -1;
|
78
92
|
}
|
79
93
|
|
80
94
|
static redisContext *connect(struct config config) {
|
@@ -84,12 +98,24 @@ static redisContext *connect(struct config config) {
|
|
84
98
|
c = redisConnect(config.tcp.host, config.tcp.port);
|
85
99
|
} else if (config.type == CONN_UNIX) {
|
86
100
|
c = redisConnectUnix(config.unix.path);
|
101
|
+
} else if (config.type == CONN_FD) {
|
102
|
+
/* Create a dummy connection just to get an fd to inherit */
|
103
|
+
redisContext *dummy_ctx = redisConnectUnix(config.unix.path);
|
104
|
+
if (dummy_ctx) {
|
105
|
+
int fd = disconnect(dummy_ctx, 1);
|
106
|
+
printf("Connecting to inherited fd %d\n", fd);
|
107
|
+
c = redisConnectFd(fd);
|
108
|
+
}
|
87
109
|
} else {
|
88
110
|
assert(NULL);
|
89
111
|
}
|
90
112
|
|
91
|
-
if (c
|
113
|
+
if (c == NULL) {
|
114
|
+
printf("Connection error: can't allocate redis context\n");
|
115
|
+
exit(1);
|
116
|
+
} else if (c->err) {
|
92
117
|
printf("Connection error: %s\n", c->errstr);
|
118
|
+
redisFree(c);
|
93
119
|
exit(1);
|
94
120
|
}
|
95
121
|
|
@@ -125,13 +151,13 @@ static void test_format_commands(void) {
|
|
125
151
|
free(cmd);
|
126
152
|
|
127
153
|
test("Format command with %%b string interpolation: ");
|
128
|
-
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
|
154
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
|
129
155
|
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
|
130
156
|
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
131
157
|
free(cmd);
|
132
158
|
|
133
159
|
test("Format command with %%b and an empty string: ");
|
134
|
-
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
|
160
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
|
135
161
|
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
|
136
162
|
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
137
163
|
free(cmd);
|
@@ -177,7 +203,7 @@ static void test_format_commands(void) {
|
|
177
203
|
FLOAT_WIDTH_TEST(double);
|
178
204
|
|
179
205
|
test("Format command with invalid printf format: ");
|
180
|
-
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",3);
|
206
|
+
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
|
181
207
|
test_cond(len == -1);
|
182
208
|
|
183
209
|
const char *argv[3];
|
@@ -200,10 +226,33 @@ static void test_format_commands(void) {
|
|
200
226
|
free(cmd);
|
201
227
|
}
|
202
228
|
|
229
|
+
static void test_append_formatted_commands(struct config config) {
|
230
|
+
redisContext *c;
|
231
|
+
redisReply *reply;
|
232
|
+
char *cmd;
|
233
|
+
int len;
|
234
|
+
|
235
|
+
c = connect(config);
|
236
|
+
|
237
|
+
test("Append format command: ");
|
238
|
+
|
239
|
+
len = redisFormatCommand(&cmd, "SET foo bar");
|
240
|
+
|
241
|
+
test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
|
242
|
+
|
243
|
+
assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
|
244
|
+
|
245
|
+
free(cmd);
|
246
|
+
freeReplyObject(reply);
|
247
|
+
|
248
|
+
disconnect(c, 0);
|
249
|
+
}
|
250
|
+
|
203
251
|
static void test_reply_reader(void) {
|
204
252
|
redisReader *reader;
|
205
253
|
void *reply;
|
206
254
|
int ret;
|
255
|
+
int i;
|
207
256
|
|
208
257
|
test("Error handling in reply parser: ");
|
209
258
|
reader = redisReaderCreate();
|
@@ -225,12 +274,13 @@ static void test_reply_reader(void) {
|
|
225
274
|
strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
|
226
275
|
redisReaderFree(reader);
|
227
276
|
|
228
|
-
test("Set error on nested multi bulks with depth >
|
277
|
+
test("Set error on nested multi bulks with depth > 7: ");
|
229
278
|
reader = redisReaderCreate();
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
279
|
+
|
280
|
+
for (i = 0; i < 9; i++) {
|
281
|
+
redisReaderFeed(reader,(char*)"*1\r\n",4);
|
282
|
+
}
|
283
|
+
|
234
284
|
ret = redisReaderGetReply(reader,NULL);
|
235
285
|
test_cond(ret == REDIS_ERR &&
|
236
286
|
strncasecmp(reader->errstr,"No support for",14) == 0);
|
@@ -277,14 +327,32 @@ static void test_reply_reader(void) {
|
|
277
327
|
redisReaderFree(reader);
|
278
328
|
}
|
279
329
|
|
330
|
+
static void test_free_null(void) {
|
331
|
+
void *redisContext = NULL;
|
332
|
+
void *reply = NULL;
|
333
|
+
|
334
|
+
test("Don't fail when redisFree is passed a NULL value: ");
|
335
|
+
redisFree(redisContext);
|
336
|
+
test_cond(redisContext == NULL);
|
337
|
+
|
338
|
+
test("Don't fail when freeReplyObject is passed a NULL value: ");
|
339
|
+
freeReplyObject(reply);
|
340
|
+
test_cond(reply == NULL);
|
341
|
+
}
|
342
|
+
|
280
343
|
static void test_blocking_connection_errors(void) {
|
281
344
|
redisContext *c;
|
282
345
|
|
283
346
|
test("Returns error when host cannot be resolved: ");
|
284
|
-
c = redisConnect((char*)"idontexist.
|
347
|
+
c = redisConnect((char*)"idontexist.test", 6379);
|
285
348
|
test_cond(c->err == REDIS_ERR_OTHER &&
|
286
349
|
(strcmp(c->errstr,"Name or service not known") == 0 ||
|
287
|
-
strcmp(c->errstr,"Can't resolve: idontexist.
|
350
|
+
strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
|
351
|
+
strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
|
352
|
+
strcmp(c->errstr,"No address associated with hostname") == 0 ||
|
353
|
+
strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
|
354
|
+
strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 ||
|
355
|
+
strcmp(c->errstr,"no address associated with name") == 0));
|
288
356
|
redisFree(c);
|
289
357
|
|
290
358
|
test("Returns error when the port is not open: ");
|
@@ -326,7 +394,7 @@ static void test_blocking_connection(struct config config) {
|
|
326
394
|
freeReplyObject(reply);
|
327
395
|
|
328
396
|
test("%%b String interpolation works: ");
|
329
|
-
reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11);
|
397
|
+
reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
|
330
398
|
freeReplyObject(reply);
|
331
399
|
reply = redisCommand(c,"GET foo");
|
332
400
|
test_cond(reply->type == REDIS_REPLY_STRING &&
|
@@ -374,7 +442,53 @@ static void test_blocking_connection(struct config config) {
|
|
374
442
|
strcasecmp(reply->element[1]->str,"pong") == 0);
|
375
443
|
freeReplyObject(reply);
|
376
444
|
|
377
|
-
disconnect(c);
|
445
|
+
disconnect(c, 0);
|
446
|
+
}
|
447
|
+
|
448
|
+
static void test_blocking_connection_timeouts(struct config config) {
|
449
|
+
redisContext *c;
|
450
|
+
redisReply *reply;
|
451
|
+
ssize_t s;
|
452
|
+
const char *cmd = "DEBUG SLEEP 3\r\n";
|
453
|
+
struct timeval tv;
|
454
|
+
|
455
|
+
c = connect(config);
|
456
|
+
test("Successfully completes a command when the timeout is not exceeded: ");
|
457
|
+
reply = redisCommand(c,"SET foo fast");
|
458
|
+
freeReplyObject(reply);
|
459
|
+
tv.tv_sec = 0;
|
460
|
+
tv.tv_usec = 10000;
|
461
|
+
redisSetTimeout(c, tv);
|
462
|
+
reply = redisCommand(c, "GET foo");
|
463
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
|
464
|
+
freeReplyObject(reply);
|
465
|
+
disconnect(c, 0);
|
466
|
+
|
467
|
+
c = connect(config);
|
468
|
+
test("Does not return a reply when the command times out: ");
|
469
|
+
s = write(c->fd, cmd, strlen(cmd));
|
470
|
+
tv.tv_sec = 0;
|
471
|
+
tv.tv_usec = 10000;
|
472
|
+
redisSetTimeout(c, tv);
|
473
|
+
reply = redisCommand(c, "GET foo");
|
474
|
+
test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
|
475
|
+
freeReplyObject(reply);
|
476
|
+
|
477
|
+
test("Reconnect properly reconnects after a timeout: ");
|
478
|
+
redisReconnect(c);
|
479
|
+
reply = redisCommand(c, "PING");
|
480
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
|
481
|
+
freeReplyObject(reply);
|
482
|
+
|
483
|
+
test("Reconnect properly uses owned parameters: ");
|
484
|
+
config.tcp.host = "foo";
|
485
|
+
config.unix.path = "foo";
|
486
|
+
redisReconnect(c);
|
487
|
+
reply = redisCommand(c, "PING");
|
488
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
|
489
|
+
freeReplyObject(reply);
|
490
|
+
|
491
|
+
disconnect(c, 0);
|
378
492
|
}
|
379
493
|
|
380
494
|
static void test_blocking_io_errors(struct config config) {
|
@@ -400,7 +514,7 @@ static void test_blocking_io_errors(struct config config) {
|
|
400
514
|
|
401
515
|
test("Returns I/O error when the connection is lost: ");
|
402
516
|
reply = redisCommand(c,"QUIT");
|
403
|
-
if (major
|
517
|
+
if (major > 2 || (major == 2 && minor > 0)) {
|
404
518
|
/* > 2.0 returns OK on QUIT and read() should be issued once more
|
405
519
|
* to know the descriptor is at EOF. */
|
406
520
|
test_cond(strcasecmp(reply->str,"OK") == 0 &&
|
@@ -428,6 +542,30 @@ static void test_blocking_io_errors(struct config config) {
|
|
428
542
|
redisFree(c);
|
429
543
|
}
|
430
544
|
|
545
|
+
static void test_invalid_timeout_errors(struct config config) {
|
546
|
+
redisContext *c;
|
547
|
+
|
548
|
+
test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
|
549
|
+
|
550
|
+
config.tcp.timeout.tv_sec = 0;
|
551
|
+
config.tcp.timeout.tv_usec = 10000001;
|
552
|
+
|
553
|
+
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
|
554
|
+
|
555
|
+
test_cond(c->err == REDIS_ERR_IO);
|
556
|
+
redisFree(c);
|
557
|
+
|
558
|
+
test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
|
559
|
+
|
560
|
+
config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
|
561
|
+
config.tcp.timeout.tv_usec = 0;
|
562
|
+
|
563
|
+
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
|
564
|
+
|
565
|
+
test_cond(c->err == REDIS_ERR_IO);
|
566
|
+
redisFree(c);
|
567
|
+
}
|
568
|
+
|
431
569
|
static void test_throughput(struct config config) {
|
432
570
|
redisContext *c = connect(config);
|
433
571
|
redisReply **replies;
|
@@ -490,7 +628,7 @@ static void test_throughput(struct config config) {
|
|
490
628
|
free(replies);
|
491
629
|
printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
|
492
630
|
|
493
|
-
disconnect(c);
|
631
|
+
disconnect(c, 0);
|
494
632
|
}
|
495
633
|
|
496
634
|
// static long __test_callback_flags = 0;
|
@@ -603,6 +741,7 @@ int main(int argc, char **argv) {
|
|
603
741
|
}
|
604
742
|
};
|
605
743
|
int throughput = 1;
|
744
|
+
int test_inherit_fd = 1;
|
606
745
|
|
607
746
|
/* Ignore broken pipe signal (for I/O error tests). */
|
608
747
|
signal(SIGPIPE, SIG_IGN);
|
@@ -621,6 +760,8 @@ int main(int argc, char **argv) {
|
|
621
760
|
cfg.unix.path = argv[0];
|
622
761
|
} else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
|
623
762
|
throughput = 0;
|
763
|
+
} else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
|
764
|
+
test_inherit_fd = 0;
|
624
765
|
} else {
|
625
766
|
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
|
626
767
|
exit(1);
|
@@ -631,19 +772,31 @@ int main(int argc, char **argv) {
|
|
631
772
|
test_format_commands();
|
632
773
|
test_reply_reader();
|
633
774
|
test_blocking_connection_errors();
|
775
|
+
test_free_null();
|
634
776
|
|
635
777
|
printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
|
636
778
|
cfg.type = CONN_TCP;
|
637
779
|
test_blocking_connection(cfg);
|
780
|
+
test_blocking_connection_timeouts(cfg);
|
638
781
|
test_blocking_io_errors(cfg);
|
782
|
+
test_invalid_timeout_errors(cfg);
|
783
|
+
test_append_formatted_commands(cfg);
|
639
784
|
if (throughput) test_throughput(cfg);
|
640
785
|
|
641
786
|
printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
|
642
787
|
cfg.type = CONN_UNIX;
|
643
788
|
test_blocking_connection(cfg);
|
789
|
+
test_blocking_connection_timeouts(cfg);
|
644
790
|
test_blocking_io_errors(cfg);
|
645
791
|
if (throughput) test_throughput(cfg);
|
646
792
|
|
793
|
+
if (test_inherit_fd) {
|
794
|
+
printf("\nTesting against inherited fd (%s):\n", cfg.unix.path);
|
795
|
+
cfg.type = CONN_FD;
|
796
|
+
test_blocking_connection(cfg);
|
797
|
+
}
|
798
|
+
|
799
|
+
|
647
800
|
if (fails) {
|
648
801
|
printf("*** %d TESTS FAILED ***\n", fails);
|
649
802
|
return 1;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#ifndef _WIN32_HELPER_INCLUDE
|
2
|
+
#define _WIN32_HELPER_INCLUDE
|
3
|
+
#ifdef _MSC_VER
|
4
|
+
|
5
|
+
#ifndef inline
|
6
|
+
#define inline __inline
|
7
|
+
#endif
|
8
|
+
|
9
|
+
#ifndef va_copy
|
10
|
+
#define va_copy(d,s) ((d) = (s))
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#ifndef snprintf
|
14
|
+
#define snprintf c99_snprintf
|
15
|
+
|
16
|
+
__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
|
17
|
+
{
|
18
|
+
int count = -1;
|
19
|
+
|
20
|
+
if (size != 0)
|
21
|
+
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
22
|
+
if (count == -1)
|
23
|
+
count = _vscprintf(format, ap);
|
24
|
+
|
25
|
+
return count;
|
26
|
+
}
|
27
|
+
|
28
|
+
__inline int c99_snprintf(char* str, size_t size, const char* format, ...)
|
29
|
+
{
|
30
|
+
int count;
|
31
|
+
va_list ap;
|
32
|
+
|
33
|
+
va_start(ap, format);
|
34
|
+
count = c99_vsnprintf(str, size, format, ap);
|
35
|
+
va_end(ap);
|
36
|
+
|
37
|
+
return count;
|
38
|
+
}
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#endif
|
42
|
+
#endif
|
data/librb/durable.rb
CHANGED
@@ -427,9 +427,17 @@ module Durable
|
|
427
427
|
rule_name = "r_#{index}"
|
428
428
|
rule = nil
|
429
429
|
if block
|
430
|
-
run_lambda =
|
431
|
-
|
432
|
-
|
430
|
+
run_lambda = nil
|
431
|
+
if block.arity < 2
|
432
|
+
run_lambda = -> c {
|
433
|
+
c.instance_exec c, &block
|
434
|
+
}
|
435
|
+
else
|
436
|
+
run_lambda = -> (c, complete) {
|
437
|
+
c.instance_exec c, complete, &block
|
438
|
+
}
|
439
|
+
end
|
440
|
+
|
433
441
|
rule = operator ? {operator => expression_definition, :run => run_lambda} : {:run => run_lambda}
|
434
442
|
else
|
435
443
|
rule = operator ? {operator => expression_definition} : {}
|
@@ -475,8 +483,18 @@ module Durable
|
|
475
483
|
def to(state_name, rule = nil, &block)
|
476
484
|
rule = define_rule(nil, nil, {}, &block) if !rule
|
477
485
|
rule[:to] = state_name
|
478
|
-
if block
|
479
|
-
|
486
|
+
if block
|
487
|
+
if block.arity < 2
|
488
|
+
rule[:run] = -> c {
|
489
|
+
c.instance_exec c, &block
|
490
|
+
}
|
491
|
+
else
|
492
|
+
rule[:run] = -> (c, complete) {
|
493
|
+
c.instance_exec c, complete, &block
|
494
|
+
}
|
495
|
+
end
|
496
|
+
else
|
497
|
+
rule[:run] = -> c {}
|
480
498
|
end
|
481
499
|
self
|
482
500
|
end
|
@@ -536,7 +554,18 @@ module Durable
|
|
536
554
|
|
537
555
|
def stage(stage_name, &block)
|
538
556
|
if block
|
539
|
-
|
557
|
+
run_lambda = nil
|
558
|
+
if block.arity < 2
|
559
|
+
run_lambda = -> c {
|
560
|
+
c.instance_exec c, &block
|
561
|
+
}
|
562
|
+
else
|
563
|
+
run_lambda = -> (c, complete) {
|
564
|
+
c.instance_exec c, complete, &block
|
565
|
+
}
|
566
|
+
end
|
567
|
+
|
568
|
+
@stages[stage_name] = {:run => run_lambda, :to => {}}
|
540
569
|
else
|
541
570
|
@stages[stage_name] = {:to => {}}
|
542
571
|
end
|