polyphony 0.43.1 → 0.43.2
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 +4 -4
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +0 -1
- data/examples/adapters/redis_blpop.rb +12 -0
- data/ext/polyphony/libev_agent.c +150 -143
- data/ext/polyphony/libev_queue.c +5 -4
- data/lib/polyphony/adapters/redis.rb +3 -2
- data/lib/polyphony/version.rb +1 -1
- data/test/test_agent.rb +12 -6
- data/test/test_global_api.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7cf8c345b125c9a41ca7c0ad025ac21d001fc1f73dedb0b4968e426a096d8b6
|
4
|
+
data.tar.gz: 23b828449792dc3887c75ad54da3451696de66f6aceee255d8a1a5e9489bdf90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a35a60f273a1989d31155a0d9c6d0a3685794dc363cb60fbf77cce4f8d4f15f7c16c6489d63d4534dc20b281fe0a9aa65f036ffa478e689d119679db48d7a52f
|
7
|
+
data.tar.gz: 8de219230c3a1ae3a6c7b618d271a58c54abe8ab5208a338e935c823056b6edebf6d311b4d90748ca9aad238f6b67643a3ac71036a60700920859bcffde56acd
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# Polyphony - Fine-Grained Concurrency for Ruby
|
2
2
|
|
3
|
-
|
4
3
|
[](http://rubygems.org/gems/polyphony)
|
5
4
|
[](https://github.com/digital-fabric/polyphony/actions?query=workflow%3ATests)
|
6
5
|
[](https://github.com/digital-fabric/polyphony/blob/master/LICENSE)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony/adapters/redis'
|
5
|
+
# require 'redis'
|
6
|
+
|
7
|
+
redis = Redis.new(host: ENV['REDISHOST'] || 'localhost')
|
8
|
+
|
9
|
+
redis.lpush("queue_key", "omgvalue")
|
10
|
+
puts "len: #{redis.llen("queue_key")}"
|
11
|
+
result = redis.blpop("queue_key")
|
12
|
+
puts result.inspect
|
data/ext/polyphony/libev_agent.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
#include <netdb.h>
|
2
|
+
#include <sys/socket.h>
|
3
|
+
|
1
4
|
#include "polyphony.h"
|
2
5
|
#include "../libev/ev.h"
|
3
|
-
#include <sys/socket.h>
|
4
6
|
|
5
7
|
VALUE cLibevAgent = Qnil;
|
6
8
|
VALUE cTCPSocket;
|
@@ -128,7 +130,7 @@ VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue
|
|
128
130
|
GetLibevAgent(self, agent);
|
129
131
|
|
130
132
|
if (is_nowait) {
|
131
|
-
|
133
|
+
long runnable_count = RARRAY_LEN(queue);
|
132
134
|
agent->run_no_wait_count++;
|
133
135
|
if (agent->run_no_wait_count < runnable_count || agent->run_no_wait_count < 10)
|
134
136
|
return self;
|
@@ -234,7 +236,7 @@ struct libev_io {
|
|
234
236
|
VALUE fiber;
|
235
237
|
};
|
236
238
|
|
237
|
-
|
239
|
+
void LibevAgent_io_callback(EV_P_ ev_io *w, int revents)
|
238
240
|
{
|
239
241
|
struct libev_io *watcher = (struct libev_io *)w;
|
240
242
|
Fiber_make_runnable(watcher->fiber, Qnil);
|
@@ -255,11 +257,31 @@ VALUE libev_agent_await(VALUE self) {
|
|
255
257
|
return libev_await(agent);
|
256
258
|
}
|
257
259
|
|
260
|
+
VALUE libev_io_wait(struct LibevAgent_t *agent, struct libev_io *watcher, rb_io_t *fptr, int flags) {
|
261
|
+
VALUE switchpoint_result;
|
262
|
+
|
263
|
+
if (watcher->fiber == Qnil) {
|
264
|
+
watcher->fiber = rb_fiber_current();
|
265
|
+
ev_io_init(&watcher->io, LibevAgent_io_callback, fptr->fd, flags);
|
266
|
+
}
|
267
|
+
ev_io_start(agent->ev_loop, &watcher->io);
|
268
|
+
switchpoint_result = libev_await(agent);
|
269
|
+
ev_io_stop(agent->ev_loop, &watcher->io);
|
270
|
+
|
271
|
+
RB_GC_GUARD(switchpoint_result);
|
272
|
+
return switchpoint_result;
|
273
|
+
}
|
274
|
+
|
275
|
+
VALUE libev_snooze() {
|
276
|
+
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
277
|
+
return Thread_switch_fiber(rb_thread_current());
|
278
|
+
}
|
279
|
+
|
258
280
|
VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
|
259
281
|
struct LibevAgent_t *agent;
|
260
282
|
struct libev_io watcher;
|
261
283
|
rb_io_t *fptr;
|
262
|
-
|
284
|
+
long len = NUM2INT(length);
|
263
285
|
int shrinkable = io_setstrbuf(&str, len);
|
264
286
|
char *buf = RSTRING_PTR(str);
|
265
287
|
long total = 0;
|
@@ -277,41 +299,25 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
|
|
277
299
|
OBJ_TAINT(str);
|
278
300
|
|
279
301
|
while (len > 0) {
|
280
|
-
|
281
|
-
if (n
|
282
|
-
|
283
|
-
|
302
|
+
ssize_t n = read(fptr->fd, buf, len);
|
303
|
+
if (n < 0) {
|
304
|
+
int e = errno;
|
305
|
+
if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
|
306
|
+
|
307
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
308
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
309
|
+
}
|
310
|
+
else {
|
311
|
+
switchpoint_result = libev_snooze();
|
312
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
313
|
+
|
314
|
+
if (n == 0) break; // EOF
|
315
|
+
|
284
316
|
total = total + n;
|
285
317
|
buf += n;
|
286
318
|
len -= n;
|
287
319
|
if (!read_to_eof || (len == 0)) break;
|
288
320
|
}
|
289
|
-
else {
|
290
|
-
int e = errno;
|
291
|
-
if ((e == EWOULDBLOCK || e == EAGAIN)) {
|
292
|
-
if (watcher.fiber == Qnil) {
|
293
|
-
watcher.fiber = rb_fiber_current();
|
294
|
-
ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_READ);
|
295
|
-
}
|
296
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
297
|
-
switchpoint_result = libev_await(agent);
|
298
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
299
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
300
|
-
goto error;
|
301
|
-
}
|
302
|
-
}
|
303
|
-
else
|
304
|
-
rb_syserr_fail(e, strerror(e));
|
305
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
306
|
-
}
|
307
|
-
}
|
308
|
-
|
309
|
-
if (watcher.fiber == Qnil) {
|
310
|
-
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
311
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
312
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
313
|
-
goto error;
|
314
|
-
}
|
315
321
|
}
|
316
322
|
|
317
323
|
if (total == 0) return Qnil;
|
@@ -347,8 +353,8 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
347
353
|
struct libev_io watcher;
|
348
354
|
rb_io_t *fptr;
|
349
355
|
VALUE str;
|
350
|
-
|
351
|
-
|
356
|
+
long total;
|
357
|
+
long len = 8192;
|
352
358
|
int shrinkable;
|
353
359
|
char *buf;
|
354
360
|
VALUE switchpoint_result = Qnil;
|
@@ -366,10 +372,20 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
366
372
|
OBJ_TAINT(str);
|
367
373
|
|
368
374
|
while (1) {
|
369
|
-
|
370
|
-
if (n
|
371
|
-
|
372
|
-
|
375
|
+
ssize_t n = read(fptr->fd, buf, len);
|
376
|
+
if (n < 0) {
|
377
|
+
int e = errno;
|
378
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
379
|
+
|
380
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
381
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
382
|
+
}
|
383
|
+
else {
|
384
|
+
switchpoint_result = libev_snooze();
|
385
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
386
|
+
|
387
|
+
if (n == 0) break; // EOF
|
388
|
+
|
373
389
|
total = n;
|
374
390
|
YIELD_STR();
|
375
391
|
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
@@ -378,24 +394,6 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
378
394
|
goto error;
|
379
395
|
}
|
380
396
|
}
|
381
|
-
else {
|
382
|
-
int e = errno;
|
383
|
-
if ((e == EWOULDBLOCK || e == EAGAIN)) {
|
384
|
-
if (watcher.fiber == Qnil) {
|
385
|
-
watcher.fiber = rb_fiber_current();
|
386
|
-
ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_READ);
|
387
|
-
}
|
388
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
389
|
-
switchpoint_result = libev_await(agent);
|
390
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
391
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
392
|
-
goto error;
|
393
|
-
}
|
394
|
-
}
|
395
|
-
else
|
396
|
-
rb_syserr_fail(e, strerror(e));
|
397
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
398
|
-
}
|
399
397
|
}
|
400
398
|
|
401
399
|
RB_GC_GUARD(str);
|
@@ -414,8 +412,8 @@ VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
|
|
414
412
|
VALUE switchpoint_result = Qnil;
|
415
413
|
|
416
414
|
char *buf = StringValuePtr(str);
|
417
|
-
|
418
|
-
|
415
|
+
long len = RSTRING_LEN(str);
|
416
|
+
long left = len;
|
419
417
|
|
420
418
|
VALUE underlying_io = rb_iv_get(io, "@io");
|
421
419
|
if (underlying_io != Qnil) io = underlying_io;
|
@@ -425,37 +423,20 @@ VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
|
|
425
423
|
watcher.fiber = Qnil;
|
426
424
|
|
427
425
|
while (left > 0) {
|
428
|
-
|
429
|
-
if (
|
426
|
+
ssize_t n = write(fptr->fd, buf, left);
|
427
|
+
if (n < 0) {
|
430
428
|
int e = errno;
|
431
|
-
if (e
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
}
|
436
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
437
|
-
switchpoint_result = libev_await(agent);
|
438
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
439
|
-
if (TEST_EXCEPTION(switchpoint_result))
|
440
|
-
goto error;
|
441
|
-
}
|
442
|
-
else {
|
443
|
-
rb_syserr_fail(e, strerror(e));
|
444
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
445
|
-
|
446
|
-
}
|
429
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
430
|
+
|
431
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
|
432
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
447
433
|
}
|
448
434
|
else {
|
449
|
-
|
450
|
-
|
451
|
-
}
|
452
|
-
}
|
435
|
+
switchpoint_result = libev_snooze();
|
436
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
453
437
|
|
454
|
-
|
455
|
-
|
456
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
457
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
458
|
-
goto error;
|
438
|
+
buf += n;
|
439
|
+
left -= n;
|
459
440
|
}
|
460
441
|
}
|
461
442
|
|
@@ -488,50 +469,39 @@ VALUE LibevAgent_accept(VALUE self, VALUE sock) {
|
|
488
469
|
fd = accept(fptr->fd, &addr, &len);
|
489
470
|
if (fd < 0) {
|
490
471
|
int e = errno;
|
491
|
-
if (e
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
}
|
496
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
497
|
-
switchpoint_result = libev_await(agent);
|
498
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
499
|
-
|
500
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
501
|
-
RB_GC_GUARD(watcher.fiber);
|
502
|
-
RB_GC_GUARD(switchpoint_result);
|
503
|
-
}
|
504
|
-
else
|
505
|
-
rb_syserr_fail(e, strerror(e));
|
506
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
472
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
473
|
+
|
474
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
475
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
507
476
|
}
|
508
477
|
else {
|
509
|
-
VALUE
|
478
|
+
VALUE socket;
|
510
479
|
rb_io_t *fp;
|
511
|
-
|
480
|
+
switchpoint_result = libev_snooze();
|
481
|
+
if (TEST_EXCEPTION(switchpoint_result)) {
|
482
|
+
close(fd); // close fd since we're raising an exception
|
483
|
+
goto error;
|
484
|
+
}
|
485
|
+
|
486
|
+
socket = rb_obj_alloc(cTCPSocket);
|
487
|
+
MakeOpenFile(socket, fp);
|
512
488
|
rb_update_max_fd(fd);
|
513
489
|
fp->fd = fd;
|
514
490
|
fp->mode = FMODE_READWRITE | FMODE_DUPLEX;
|
515
|
-
rb_io_ascii8bit_binmode(
|
491
|
+
rb_io_ascii8bit_binmode(socket);
|
516
492
|
rb_io_set_nonblock(fp);
|
517
493
|
rb_io_synchronized(fp);
|
518
494
|
|
519
495
|
// if (rsock_do_not_reverse_lookup) {
|
520
496
|
// fp->mode |= FMODE_NOREVLOOKUP;
|
521
497
|
// }
|
522
|
-
|
523
|
-
if (watcher.fiber == Qnil) {
|
524
|
-
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
525
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
526
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
527
|
-
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
528
|
-
}
|
529
|
-
}
|
530
|
-
|
531
|
-
return connection;
|
498
|
+
return socket;
|
532
499
|
}
|
533
500
|
}
|
501
|
+
RB_GC_GUARD(switchpoint_result);
|
534
502
|
return Qnil;
|
503
|
+
error:
|
504
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
535
505
|
}
|
536
506
|
|
537
507
|
VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
@@ -542,7 +512,7 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
|
542
512
|
struct sockaddr addr;
|
543
513
|
socklen_t len = (socklen_t)sizeof addr;
|
544
514
|
VALUE switchpoint_result = Qnil;
|
545
|
-
VALUE
|
515
|
+
VALUE socket = Qnil;
|
546
516
|
VALUE underlying_sock = rb_iv_get(sock, "@io");
|
547
517
|
if (underlying_sock != Qnil) sock = underlying_sock;
|
548
518
|
|
@@ -555,46 +525,82 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
|
555
525
|
fd = accept(fptr->fd, &addr, &len);
|
556
526
|
if (fd < 0) {
|
557
527
|
int e = errno;
|
558
|
-
if (e
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
}
|
563
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
564
|
-
switchpoint_result = libev_await(agent);
|
565
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
566
|
-
|
567
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
568
|
-
}
|
569
|
-
else
|
570
|
-
rb_syserr_fail(e, strerror(e));
|
571
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
528
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
529
|
+
|
530
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
531
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
572
532
|
}
|
573
533
|
else {
|
574
534
|
rb_io_t *fp;
|
575
|
-
|
576
|
-
|
535
|
+
switchpoint_result = libev_snooze();
|
536
|
+
if (TEST_EXCEPTION(switchpoint_result)) {
|
537
|
+
close(fd); // close fd since we're raising an exception
|
538
|
+
goto error;
|
539
|
+
}
|
540
|
+
|
541
|
+
socket = rb_obj_alloc(cTCPSocket);
|
542
|
+
MakeOpenFile(socket, fp);
|
577
543
|
rb_update_max_fd(fd);
|
578
544
|
fp->fd = fd;
|
579
545
|
fp->mode = FMODE_READWRITE | FMODE_DUPLEX;
|
580
|
-
rb_io_ascii8bit_binmode(
|
546
|
+
rb_io_ascii8bit_binmode(socket);
|
581
547
|
rb_io_set_nonblock(fp);
|
582
548
|
rb_io_synchronized(fp);
|
583
549
|
|
584
|
-
rb_yield(
|
585
|
-
|
586
|
-
|
587
|
-
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
588
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
589
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
550
|
+
rb_yield(socket);
|
551
|
+
socket = Qnil;
|
590
552
|
}
|
591
553
|
}
|
592
554
|
|
593
|
-
RB_GC_GUARD(
|
555
|
+
RB_GC_GUARD(socket);
|
594
556
|
RB_GC_GUARD(watcher.fiber);
|
595
557
|
RB_GC_GUARD(switchpoint_result);
|
558
|
+
return Qnil;
|
559
|
+
error:
|
560
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
596
561
|
}
|
597
562
|
|
563
|
+
// VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
|
564
|
+
// struct LibevAgent_t *agent;
|
565
|
+
// struct libev_io watcher;
|
566
|
+
// rb_io_t *fptr;
|
567
|
+
// struct sockaddr_in addr;
|
568
|
+
// char *host_buf = StringValueCStr(host);
|
569
|
+
// VALUE switchpoint_result = Qnil;
|
570
|
+
// VALUE underlying_sock = rb_iv_get(sock, "@io");
|
571
|
+
// if (underlying_sock != Qnil) sock = underlying_sock;
|
572
|
+
|
573
|
+
// GetLibevAgent(self, agent);
|
574
|
+
// GetOpenFile(sock, fptr);
|
575
|
+
// rb_io_set_nonblock(fptr);
|
576
|
+
// watcher.fiber = Qnil;
|
577
|
+
|
578
|
+
// addr.sin_family = AF_INET;
|
579
|
+
// addr.sin_addr.s_addr = inet_addr(host_buf);
|
580
|
+
// addr.sin_port = htons(NUM2INT(port));
|
581
|
+
|
582
|
+
// while (1) {
|
583
|
+
// int result = connect(fptr->fd, &addr, sizeof(addr));
|
584
|
+
// if (result < 0) {
|
585
|
+
// int e = errno;
|
586
|
+
// if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
587
|
+
|
588
|
+
// switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
|
589
|
+
// if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
590
|
+
// }
|
591
|
+
// else {
|
592
|
+
// switchpoint_result = libev_snooze();
|
593
|
+
// if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
594
|
+
|
595
|
+
// return sock;
|
596
|
+
// }
|
597
|
+
// }
|
598
|
+
// RB_GC_GUARD(switchpoint_result);
|
599
|
+
// return Qnil;
|
600
|
+
// error:
|
601
|
+
// return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
602
|
+
// }
|
603
|
+
|
598
604
|
VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write) {
|
599
605
|
struct LibevAgent_t *agent;
|
600
606
|
struct libev_io watcher;
|
@@ -624,7 +630,7 @@ struct libev_timer {
|
|
624
630
|
VALUE fiber;
|
625
631
|
};
|
626
632
|
|
627
|
-
|
633
|
+
void LibevAgent_timer_callback(EV_P_ ev_timer *w, int revents)
|
628
634
|
{
|
629
635
|
struct libev_timer *watcher = (struct libev_timer *)w;
|
630
636
|
Fiber_make_runnable(watcher->fiber, Qnil);
|
@@ -654,7 +660,7 @@ struct libev_child {
|
|
654
660
|
VALUE fiber;
|
655
661
|
};
|
656
662
|
|
657
|
-
|
663
|
+
void LibevAgent_child_callback(EV_P_ ev_child *w, int revents)
|
658
664
|
{
|
659
665
|
struct libev_child *watcher = (struct libev_child *)w;
|
660
666
|
int exit_status = w->rstatus >> 8; // weird, why should we do this?
|
@@ -712,6 +718,7 @@ void Init_LibevAgent() {
|
|
712
718
|
rb_define_method(cLibevAgent, "write", LibevAgent_write, 2);
|
713
719
|
rb_define_method(cLibevAgent, "accept", LibevAgent_accept, 1);
|
714
720
|
rb_define_method(cLibevAgent, "accept_loop", LibevAgent_accept_loop, 1);
|
721
|
+
// rb_define_method(cLibevAgent, "connect", LibevAgent_accept, 3);
|
715
722
|
rb_define_method(cLibevAgent, "wait_io", LibevAgent_wait_io, 2);
|
716
723
|
rb_define_method(cLibevAgent, "sleep", LibevAgent_sleep, 1);
|
717
724
|
rb_define_method(cLibevAgent, "waitpid", LibevAgent_waitpid, 1);
|
data/ext/polyphony/libev_queue.c
CHANGED
@@ -120,11 +120,12 @@ static VALUE LibevQueue_initialize(VALUE self) {
|
|
120
120
|
|
121
121
|
VALUE LibevQueue_push(VALUE self, VALUE value) {
|
122
122
|
LibevQueue_t *queue;
|
123
|
-
struct async_watcher *watcher;
|
124
123
|
GetQueue(self, queue);
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
if (queue->shift_queue.count > 0) {
|
125
|
+
struct async_watcher *watcher = async_queue_pop(&queue->shift_queue);
|
126
|
+
if (watcher) {
|
127
|
+
ev_async_send(watcher->ev_loop, &watcher->async);
|
128
|
+
}
|
128
129
|
}
|
129
130
|
rb_ary_push(queue->items, value);
|
130
131
|
return self;
|
@@ -6,7 +6,7 @@ require 'redis'
|
|
6
6
|
require 'hiredis/reader'
|
7
7
|
|
8
8
|
# Polyphony-based Redis driver
|
9
|
-
class
|
9
|
+
class Polyphony::RedisDriver
|
10
10
|
def self.connect(config)
|
11
11
|
raise 'unix sockets not supported' if config[:scheme] == 'unix'
|
12
12
|
|
@@ -43,6 +43,7 @@ class Driver
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def format_command(args)
|
46
|
+
args = args.flatten
|
46
47
|
(+"*#{args.size}\r\n").tap do |s|
|
47
48
|
args.each do |a|
|
48
49
|
a = a.to_s
|
@@ -63,4 +64,4 @@ class Driver
|
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
|
-
Redis::Connection.drivers <<
|
67
|
+
Redis::Connection.drivers << Polyphony::RedisDriver
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_agent.rb
CHANGED
@@ -21,10 +21,13 @@ class AgentTest < MiniTest::Test
|
|
21
21
|
spin {
|
22
22
|
@agent.sleep 0.01
|
23
23
|
count += 1
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
@agent.sleep 0.01
|
25
|
+
count += 1
|
26
|
+
@agent.sleep 0.01
|
27
|
+
count += 1
|
28
|
+
}.await
|
29
|
+
assert Time.now - t0 >= 0.03
|
30
|
+
assert_equal 3, count
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_write_read_partial
|
@@ -88,10 +91,13 @@ class AgentTest < MiniTest::Test
|
|
88
91
|
buf << :done
|
89
92
|
end
|
90
93
|
|
94
|
+
# writing always causes snoozing
|
91
95
|
o << 'foo'
|
92
96
|
o << 'bar'
|
93
97
|
o.close
|
94
|
-
|
98
|
+
|
99
|
+
# read_loop will snooze after every read
|
100
|
+
4.times { snooze }
|
95
101
|
|
96
102
|
assert_equal [:ready, 'foo', 'bar', :done], buf
|
97
103
|
end
|
@@ -110,7 +116,7 @@ class AgentTest < MiniTest::Test
|
|
110
116
|
assert_equal 1, clients.size
|
111
117
|
|
112
118
|
c2 = TCPSocket.new('127.0.0.1', 1234)
|
113
|
-
snooze
|
119
|
+
2.times { snooze }
|
114
120
|
|
115
121
|
assert_equal 2, clients.size
|
116
122
|
|
data/test/test_global_api.rb
CHANGED
@@ -145,7 +145,7 @@ class CancelAfterTest < MiniTest::Test
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
t1 = Time.now
|
148
|
-
assert t1 - t0 < 0.
|
148
|
+
assert t1 - t0 < 0.1
|
149
149
|
end
|
150
150
|
|
151
151
|
def test_cancel_after_without_block
|
@@ -157,7 +157,7 @@ class CancelAfterTest < MiniTest::Test
|
|
157
157
|
sleep 1
|
158
158
|
end
|
159
159
|
t1 = Time.now
|
160
|
-
assert t1 - t0 < 0.
|
160
|
+
assert t1 - t0 < 0.1
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.43.
|
4
|
+
version: 0.43.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -284,6 +284,7 @@ files:
|
|
284
284
|
- examples/adapters/pg_notify.rb
|
285
285
|
- examples/adapters/pg_pool.rb
|
286
286
|
- examples/adapters/pg_transaction.rb
|
287
|
+
- examples/adapters/redis_blpop.rb
|
287
288
|
- examples/adapters/redis_channels.rb
|
288
289
|
- examples/adapters/redis_client.rb
|
289
290
|
- examples/adapters/redis_pubsub.rb
|