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 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