Skip to content

Commit

Permalink
Remove delta comparison for fillup (#8)
Browse files Browse the repository at this point in the history
It is better to let the DB compare the level to the
capacity (using it's own float representation) and to
return based on that. Since we use LEAST the value would be
equal (exactly) to capacity at overflow.

Closes #7
  • Loading branch information
julik authored Dec 16, 2023
1 parent 1c2cd7a commit 67d3dda
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [Unreleased]

- [8](https://github.com/cheddar-me/pecorino/pull/8) - Use comparisons in SQL to determine whether the leaky bucket did overflow
- [6](https://github.com/cheddar-me/pecorino/pull/6) - Changed the way Structs are defined, this does not impact the API.

## [0.1.0] - 2023-10-30
Expand Down
12 changes: 8 additions & 4 deletions lib/pecorino/leaky_bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,19 @@ def add_tokens(n_tokens)
t.level + :fillup - (EXTRACT(EPOCH FROM (EXCLUDED.last_touched_at - t.last_touched_at)) * :leak_rate)
)
)
RETURNING level
RETURNING
level,
-- Compare level to the capacity inside the DB so that we won't have rounding issues
level >= :capa AS did_overflow
SQL

# Note the use of .uncached here. The AR query cache will actually see our
# query as a repeat (since we use "select_value" for the RETURNING bit) and will not call into Postgres
# query as a repeat (since we use "select_one" for the RETURNING bit) and will not call into Postgres
# correctly, thus the clock_timestamp() value would be frozen between calls. We don't want that here.
# See https://stackoverflow.com/questions/73184531/why-would-postgres-clock-timestamp-freeze-inside-a-rails-unit-test
level_after_fillup = conn.uncached { conn.select_value(sql) }
upserted = conn.uncached { conn.select_one(sql) }
capped_level_after_fillup, did_overflow = upserted.fetch("level"), upserted.fetch("did_overflow")

State.new(level_after_fillup, (@capacity - level_after_fillup).abs < 0.01)
State.new(capped_level_after_fillup, did_overflow)
end
end

0 comments on commit 67d3dda

Please sign in to comment.