Skip to content

Commit

Permalink
transaction support for liteconnection
Browse files Browse the repository at this point in the history
  • Loading branch information
oldmoe committed Jun 8, 2024
1 parent 71a7f73 commit 5320d68
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 36 deletions.
20 changes: 8 additions & 12 deletions lib/active_support/cache/litecache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,15 @@ def initialize(options = {})
def increment(key, amount = 1, options = nil)
key = key.to_s
options = merged_options(options)
# todo: fix me
# this is currently a hack to avoid dealing with Rails cache encoding and decoding
# and it can result in a race condition as it stands
# @cache.transaction(:immediate) do
# currently transactions are not compatible with acquiring connections
# this needs fixing by storing the connection to the context once acquired
if (value = read(key, options))
value = value.to_i + amount
write(key, value, options)
else
write(key, amount, options)

@cache.transaction do
if (value = read(key, options))
value = value.to_i + amount
write(key, value, options)
else
write(key, amount, options)
end
end
# end
end

def decrement(key, amount = 1, options = nil)
Expand Down
35 changes: 12 additions & 23 deletions lib/litestack/litecache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ def initialize(options = {})
def set(key, value, expires_in = nil)
key = key.to_s
expires_in ||= @expires_in
@conn.acquire do |cache|
cache.stmts[:setter].execute!(key, value, expires_in)
begin
run_stmt(:setter, key, value, expires_in)
capture(:set, key)
rescue SQLite3::FullException
cache.stmts[:extra_pruner].execute!(0.2)
cache.execute("vacuum")
transaction do
run_stmt(extra_pruner, 0.2)
run_sql("vaccuum")
end
retry
end
true
Expand All @@ -89,11 +91,11 @@ def set_multi(keys_and_values, expires_in = nil)
transaction do |conn|
keys_and_values.each_pair do |k, v|
key = k.to_s
conn.stmts[:setter].execute!(key, v, expires_in)
run_stmt(:setter, key, v, expires_in)
capture(:set, key)
rescue SQLite3::FullException
conn.stmts[:extra_pruner].execute!(0.2)
conn.execute("vacuum")
run_stmt(extra_pruner, 0.2)
run_sql("vaccuum")
retry
end
end
Expand Down Expand Up @@ -123,7 +125,7 @@ def set_unless_exists(key, value, expires_in = nil)
# if the key doesn't exist or it is expired then null will be returned
def get(key)
key = key.to_s
if (record = @conn.acquire { |cache| cache.stmts[:getter].execute!(key)[0] })
if (record = run_stmt(:getter, key)[0])
capture(:get, key, 1)
return record[1]
end
Expand All @@ -138,7 +140,7 @@ def get_multi(*keys)
transaction(:deferred) do |conn|
keys.length.times do |i|
key = keys[i].to_s
if (record = conn.stmts[:getter].execute!(key)[0])
if (record = run_stmt(:getter, key)[0])
results[keys[i]] = record[1] # use the original key format
capture(:get, key, 1)
else
Expand Down Expand Up @@ -221,20 +223,7 @@ def snapshot
}
}
end

# low level access to SQLite transactions, use with caution
def transaction(mode = :immediate)
@conn.acquire do |cache|
if cache.transaction_active?
yield
else
cache.transaction(mode) do
yield cache
end
end
end
end


private

def setup
Expand Down
16 changes: 15 additions & 1 deletion lib/litestack/liteconnection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ def path
run_method(:filename)
end

def transaction(mode = :immediate)
with_connection do |conn|
if conn.transaction_active?
conn.transaction(mode) do
yield conn
end
else
yield conn
end
end
end

private # all methods are private

def init(options = {})
Expand Down Expand Up @@ -120,12 +132,14 @@ def with_connection
@conn.acquire do |conn|
begin
@checked_out_conn = conn
yield self
yield conn
ensure
@checked_out_conn = nil
end
end
end



def create_pooled_connection(count = 1)
count = 1 unless count&.is_a?(Integer)
Expand Down

0 comments on commit 5320d68

Please sign in to comment.