Skip to content

Commit 09d5c03

Browse files
author
Michael Kipper
committed
Review comments
1 parent 3c070d3 commit 09d5c03

File tree

7 files changed

+71
-22
lines changed

7 files changed

+71
-22
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Per the above example, you no longer need to care about the number of tickets. R
187187

188188
In this case, we'd allow 49% of the workers on a particular host to connect to this redis resource.
189189

190-
In particular, 1 worker = 1 ticket (due to `ceil`), 2 workers = 2 tickets (due to `min_tickets`), 4 workers = 2 tickets, 16 workers = 8 tickets, 100 workers = 49 tickets.
190+
In particular, 1 worker = 1 ticket (due to `ceil`), 2 workers = 2 tickets (due to `min_tickets`), 4 workers = 2 tickets (due to `ceil`), 100 workers = 49 tickets.
191191

192192
**Note**:
193193

ext/semian/resource.c

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ static VALUE
44
cleanup_semian_resource_acquire(VALUE self);
55

66
static void
7-
check_tickets_xor_quota_arg(VALUE tickets, VALUE quota);
7+
check_tickets_xor_quota_arg(VALUE tickets, VALUE min_tickets, VALUE quota);
88

99
static double
1010
check_quota_arg(VALUE quota);
1111

1212
static int
1313
check_tickets_arg(VALUE tickets);
1414

15+
static int
16+
check_min_tickets_arg(VALUE min_tickets);
17+
1518
static long
1619
check_permissions_arg(VALUE permissions);
1720

@@ -203,13 +206,13 @@ VALUE
203206
semian_resource_initialize(VALUE self, VALUE id, VALUE tickets, VALUE quota, VALUE permissions, VALUE default_timeout, VALUE min_tickets)
204207
{
205208
// Check and cast arguments
206-
check_tickets_xor_quota_arg(tickets, quota);
209+
check_tickets_xor_quota_arg(tickets, min_tickets, quota);
207210
double c_quota = check_quota_arg(quota);
208211
int c_tickets = check_tickets_arg(tickets);
209212
long c_permissions = check_permissions_arg(permissions);
210213
const char *c_id_str = check_id_arg(id);
211214
double c_timeout = check_default_timeout_arg(default_timeout);
212-
int c_min_tickets = check_tickets_arg(min_tickets);
215+
int c_min_tickets = check_min_tickets_arg(min_tickets);
213216

214217
// Build semian resource structure
215218
semian_resource_t *res = NULL;
@@ -254,10 +257,22 @@ check_permissions_arg(VALUE permissions)
254257
}
255258

256259
static void
257-
check_tickets_xor_quota_arg(VALUE tickets, VALUE quota)
260+
check_tickets_xor_quota_arg(VALUE tickets, VALUE min_tickets, VALUE quota)
258261
{
259-
if ((TYPE(tickets) == T_NIL && TYPE(quota) == T_NIL) ||(TYPE(tickets) != T_NIL && TYPE(quota) != T_NIL)){
260-
rb_raise(rb_eArgError, "Must pass exactly one of ticket or quota");
262+
const char *msg = "Must pass exactly one of ticket or quota/min_tickets";
263+
if (TYPE(quota) != T_NIL) {
264+
if (TYPE(tickets) != T_NIL) {
265+
dprintf("FOO");
266+
rb_raise(rb_eArgError, msg);
267+
}
268+
} else if (TYPE(tickets) != T_NIL) {
269+
if (TYPE(quota) != T_NIL || TYPE(min_tickets) != T_NIL) {
270+
dprintf("FOO");
271+
rb_raise(rb_eArgError, msg);
272+
}
273+
} else {
274+
dprintf("FOO");
275+
rb_raise(rb_eArgError, msg);
261276
}
262277
}
263278

@@ -303,6 +318,32 @@ check_tickets_arg(VALUE tickets)
303318
return c_tickets;
304319
}
305320

321+
static int
322+
check_min_tickets_arg(VALUE min_tickets)
323+
{
324+
int retval = -1;
325+
326+
switch (rb_type(min_tickets)) {
327+
case T_NIL:
328+
case T_UNDEF:
329+
return -1;
330+
case T_FLOAT:
331+
rb_warn("semian min_tickets value %f is a float, converting to fixnum", RFLOAT_VALUE(min_tickets));
332+
retval = (int) RFLOAT_VALUE(min_tickets);
333+
break;
334+
case T_FIXNUM:
335+
retval = FIX2LONG(min_tickets); break;
336+
default:
337+
retval = -1; break;
338+
}
339+
340+
if (retval <= 0 || retval > system_max_semaphore_count) {
341+
rb_raise(rb_eArgError, "max_tickets must be in range [1,%d)", system_max_semaphore_count);
342+
}
343+
344+
return retval;
345+
}
346+
306347
static const char*
307348
check_id_arg(VALUE id)
308349
{

ext/semian/tickets.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ max(const int a, const int b)
8080
}
8181

8282
static int
83-
calculate_quota_tickets (int sem_id, double quota, int min_tickets)
83+
calculate_quota_tickets(int sem_id, double quota, int min_tickets)
8484
{
8585
int workers = get_sem_val(sem_id, SI_SEM_REGISTERED_WORKERS);
8686
int tickets = (int) ceil(workers * quota);
87-
dprintf("Calculating quota tickets - sem_id:%d quota:%0.2f%% workers:%d min_tickets:%d tickets:%d", sem_id, quota, workers, min_tickets, tickets);
87+
dprintf("Calculating quota tickets - sem_id:%d quota:%0.2f%% workers:%d min_tickets:%d tickets:%d", sem_id, quota * 100.0, workers, min_tickets, tickets);
8888
return min_tickets > 0 ? min(workers, max(tickets, min_tickets)) : tickets;
8989
}

ext/semian/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <stdio.h>
66
#include <time.h>
77

8-
#if defined(DEBUG) || defined(SEMIAN_DEBUG)
8+
#ifdef DEBUG
99
# define DEBUG_TEST 1
1010
#else
1111
# define DEBUG_TEST 0

lib/semian/resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def instance(*args)
99
end
1010
end
1111

12-
def initialize(name, tickets: nil, quota: nil, permissions: 0660, timeout: 0, min_tickets: 1)
12+
def initialize(name, tickets: nil, quota: nil, permissions: 0660, timeout: 0, min_tickets: nil)
1313
if Semian.semaphores_enabled?
1414
initialize_semaphore(name, tickets, quota, permissions, timeout, min_tickets) if respond_to?(:initialize_semaphore)
1515
else

test/resource_test.rb

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,14 @@ def test_min_tickets
506506
assert_equal(8, resource.tickets)
507507
end
508508

509+
def test_min_tickets_float
510+
expected_warning = /semian min_tickets value 2\.000000 is a float, converting to fixnum/
511+
with_fake_std_error(warn_message: expected_warning) do
512+
id = Time.now.strftime('%H:%M:%S.%N')
513+
Semian::Resource.new(id, quota: 0.49, timeout: 0.1, min_tickets: 2.0)
514+
end
515+
end
516+
509517
def test_min_tickets_nil
510518
id = Time.now.strftime('%H:%M:%S.%N')
511519
resource = Semian::Resource.new(id, quota: 0.49, timeout: 0.1, min_tickets: nil)
@@ -522,16 +530,9 @@ def test_min_tickets_nil
522530

523531
def test_min_tickets_zero
524532
id = Time.now.strftime('%H:%M:%S.%N')
525-
resource = Semian::Resource.new(id, quota: 0.49, timeout: 0.1, min_tickets: 0)
526-
assert_equal(1, resource.tickets)
527-
fork_workers(resource: id, count: 1, quota: 0.49, min_tickets: 0, timeout: 0.1, wait_for_timeout: true)
528-
assert_equal(1, resource.tickets)
529-
fork_workers(resource: id, count: 1, quota: 0.49, min_tickets: 0, timeout: 0.1, wait_for_timeout: true)
530-
assert_equal(2, resource.tickets)
531-
fork_workers(resource: id, count: 1, quota: 0.49, min_tickets: 0, timeout: 0.1, wait_for_timeout: true)
532-
assert_equal(2, resource.tickets)
533-
fork_workers(resource: id, count: 12, quota: 0.49, min_tickets: 0, timeout: 0.1, wait_for_timeout: true)
534-
assert_equal(8, resource.tickets)
533+
assert_raises ArgumentError do
534+
Semian::Resource.new(id, quota: 0.49, timeout: 0.1, min_tickets: 0)
535+
end
535536
end
536537

537538
def test_min_tickets_negative
@@ -541,6 +542,13 @@ def test_min_tickets_negative
541542
end
542543
end
543544

545+
def test_min_tickets_out_of_range
546+
id = Time.now.strftime('%H:%M:%S.%N')
547+
assert_raises ArgumentError do
548+
Semian::Resource.new(id, quota: 0.49, timeout: 0.1, min_tickets: 32768)
549+
end
550+
end
551+
544552
def create_resource(*args)
545553
@resources ||= []
546554
resource = Semian::Resource.new(*args)

test/semian_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def test_register_with_bulkhead_missing_options
3535
circuit_breaker: false,
3636
)
3737
end
38-
assert_equal exception.message, "Must pass exactly one of ticket or quota"
38+
assert_equal exception.message, "Must pass exactly one of ticket or quota/min_tickets"
3939
end
4040

4141
def test_unsuported_constants

0 commit comments

Comments
 (0)