polyphony 0.43.1 → 0.43.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/polyphony.svg)](http://rubygems.org/gems/polyphony)
|
5
4
|
[![Modulation Test](https://github.com/digital-fabric/polyphony/workflows/Tests/badge.svg)](https://github.com/digital-fabric/polyphony/actions?query=workflow%3ATests)
|
6
5
|
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](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
|