Skip to content

Commit

Permalink
Enhance trimming to avoid locking and lag
Browse files Browse the repository at this point in the history
  • Loading branch information
npezza93 committed Sep 12, 2024
1 parent e20f037 commit 00d6a47
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
13 changes: 11 additions & 2 deletions app/jobs/solid_cable/trim_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@

module SolidCable
class TrimJob < ActiveJob::Base
def perform
::SolidCable::Message.trimmable.delete_all
def perform(id = ::SolidCable::Message.maximum(:id))
return unless (id % (trim_batch_size / 2)).zero?

::SolidCable::Message.trimmable.
limit(trim_batch_size).non_blocking_lock.delete_all
end

private

def trim_batch_size
::Solidcable.trim_batch_size
end
end
end
8 changes: 8 additions & 0 deletions app/models/solid_cable/record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@ class Record < ActiveRecord::Base
self.abstract_class = true

connects_to(**SolidCable.connects_to) if SolidCable.connects_to.present?

def self.non_blocking_lock
if SolidCable.use_skip_locked
lock(Arel.sql("FOR UPDATE SKIP LOCKED"))
else
lock
end
end
end
end
4 changes: 2 additions & 2 deletions lib/action_cable/subscription_adapter/solid_cable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ def initialize(*)
end

def broadcast(channel, payload)
::SolidCable::Message.broadcast(channel, payload)
id = ::SolidCable::Message.broadcast(channel, payload).rows.flatten.max

::SolidCable::TrimJob.perform_now if ::SolidCable.autotrim?
::SolidCable::TrimJob.perform_now(id) if ::SolidCable.autotrim?
end

def subscribe(channel, callback, success_callback = nil)
Expand Down
12 changes: 12 additions & 0 deletions lib/solid_cable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ def autotrim?
cable_config.autotrim != false
end

def trim_batch_size
if (size = cable_config.trim_batch_size.to_i).zero?
100
else
size
end
end

def use_skip_locked
cable_config.use_skip_locked != false
end

private

def cable_config
Expand Down
16 changes: 16 additions & 0 deletions test/solid_cable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,20 @@ class SolidCableTest < ActiveSupport::TestCase
assert SolidCable.autotrim?
end
end

test "default trim_batch_size is 100" do
assert_equal 100, SolidCable.trim_batch_size
end

test "trim_batch_size when set badly" do
with_cable_config trim_batch_size: "weird" do
assert_equal 100, SolidCable.trim_batch_size
end
end

test "trim_batch_size when set" do
with_cable_config trim_batch_size: 42 do
assert_equal 42, SolidCable.trim_batch_size
end
end
end

0 comments on commit 00d6a47

Please sign in to comment.