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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8bb75fb77b087726e1ff77ed4f82331e9855467965e55bda8e64a6bc93a922b9
4
- data.tar.gz: 7167af95b9a02463c81478d5f485c8dd33a14ce579b437580307554f1ad9b23e
3
+ metadata.gz: c7cf8c345b125c9a41ca7c0ad025ac21d001fc1f73dedb0b4968e426a096d8b6
4
+ data.tar.gz: 23b828449792dc3887c75ad54da3451696de66f6aceee255d8a1a5e9489bdf90
5
5
  SHA512:
6
- metadata.gz: 6df70953e104c7742248532b2cb1eaa2a0e96867a0480614e5b4966381b53b0d19236a26f8eb3986fa4e59b10e1bd32ec2517d684d17dc820ef6f558b91e624c
7
- data.tar.gz: 06e123256b1c1d66ecc4c02109341436b2c802f41358ce8531b89e64792c156435995c6fa2516b002921cf1db4679beb3a92449cc9ac5613e26d60642772cb56
6
+ metadata.gz: a35a60f273a1989d31155a0d9c6d0a3685794dc363cb60fbf77cce4f8d4f15f7c16c6489d63d4534dc20b281fe0a9aa65f036ffa478e689d119679db48d7a52f
7
+ data.tar.gz: 8de219230c3a1ae3a6c7b618d271a58c54abe8ab5208a338e935c823056b6edebf6d311b4d90748ca9aad238f6b67643a3ac71036a60700920859bcffde56acd
@@ -7,7 +7,7 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- os: [ubuntu-latest]
10
+ os: [ubuntu-latest, macos-latest]
11
11
  ruby: [2.6, 2.7]
12
12
 
13
13
  name: >-
@@ -1,3 +1,11 @@
1
+ ## 0.43.2 2020-07-07
2
+
3
+ * Fix sending Redis commands with array arguments (#21)
4
+
5
+ ## 0.43.1 2020-06
6
+
7
+ * Fix compiling C-extension on MacOS (#20)
8
+
1
9
  ## 0.43 2020-07-05
2
10
 
3
11
  * Add IO#read_loop
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.43.1)
4
+ polyphony (0.43.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
@@ -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
- int runnable_count = RARRAY_LEN(queue);
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
- static void LibevAgent_io_callback(EV_P_ ev_io *w, int revents)
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
- int len = NUM2INT(length);
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
- int n = read(fptr->fd, buf, len);
281
- if (n == 0)
282
- break;
283
- if (n > 0) {
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
- int total;
351
- int len = 8192;
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
- int n = read(fptr->fd, buf, len);
370
- if (n == 0)
371
- break;
372
- if (n > 0) {
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
- int len = RSTRING_LEN(str);
418
- int left = len;
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
- int result = write(fptr->fd, buf, left);
429
- if (result < 0) {
426
+ ssize_t n = write(fptr->fd, buf, left);
427
+ if (n < 0) {
430
428
  int e = errno;
431
- if (e == EAGAIN) {
432
- if (watcher.fiber == Qnil) {
433
- watcher.fiber = rb_fiber_current();
434
- ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_WRITE);
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
- buf += result;
450
- left -= result;
451
- }
452
- }
435
+ switchpoint_result = libev_snooze();
436
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
453
437
 
454
- if (watcher.fiber == Qnil) {
455
- Fiber_make_runnable(rb_fiber_current(), Qnil);
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 == EWOULDBLOCK || e == EAGAIN) {
492
- if (watcher.fiber == Qnil) {
493
- watcher.fiber = rb_fiber_current();
494
- ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_READ);
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 connection = rb_obj_alloc(cTCPSocket);
478
+ VALUE socket;
510
479
  rb_io_t *fp;
511
- MakeOpenFile(connection, fp);
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(connection);
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 connection = Qnil;
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 == EWOULDBLOCK || e == EAGAIN) {
559
- if (watcher.fiber == Qnil) {
560
- watcher.fiber = rb_fiber_current();
561
- ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_READ);
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
- connection = rb_obj_alloc(cTCPSocket);
576
- MakeOpenFile(connection, fp);
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(connection);
546
+ rb_io_ascii8bit_binmode(socket);
581
547
  rb_io_set_nonblock(fp);
582
548
  rb_io_synchronized(fp);
583
549
 
584
- rb_yield(connection);
585
- connection = Qnil;
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(connection);
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
- static void LibevAgent_timer_callback(EV_P_ ev_timer *w, int revents)
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
- static void LibevAgent_child_callback(EV_P_ ev_child *w, int revents)
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);
@@ -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
- watcher = async_queue_pop(&queue->shift_queue);
126
- if (watcher) {
127
- ev_async_send(watcher->ev_loop, &watcher->async);
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 Driver
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 << Driver
67
+ Redis::Connection.drivers << Polyphony::RedisDriver
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.43.1'
4
+ VERSION = '0.43.2'
5
5
  end
@@ -21,10 +21,13 @@ class AgentTest < MiniTest::Test
21
21
  spin {
22
22
  @agent.sleep 0.01
23
23
  count += 1
24
- }
25
- suspend
26
- assert Time.now - t0 >= 0.01
27
- assert_equal 1, count
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
- snooze
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
 
@@ -145,7 +145,7 @@ class CancelAfterTest < MiniTest::Test
145
145
  end
146
146
  end
147
147
  t1 = Time.now
148
- assert t1 - t0 < 0.02
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.02
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.1
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-06 00:00:00.000000000 Z
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