Skip to content

Commit

Permalink
Hash channel to have a more compact index
Browse files Browse the repository at this point in the history
  • Loading branch information
npezza93 committed Sep 12, 2024
1 parent 1eb0a84 commit 7d66d87
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 32 deletions.
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ AllCops:
- test/dummy/**/*
- bench/**/*
- test/lib/action_cable/subscription_adapter/solid_cable_test.rb
- lib/generators/**/*_schema.rb
TargetRubyVersion: 3.3

# Department Bundler
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ production:

Then run `db:prepare` in production to ensure the database is created and the schema is loaded.

If you have already installed Solid Cable, run `solid_cable:update` to get the
latest changes to migrations.

## Configuration

All configuration is managed via the `config/cable.yml` file. By default, it'll be configured like this:
Expand Down
24 changes: 23 additions & 1 deletion app/models/solid_cable/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,29 @@ class Message < SolidCable::Record
where(created_at: ..::SolidCable.message_retention.ago)
}
scope :broadcastable, lambda { |channels, last_id|
where(channel: channels).where(id: (last_id + 1)..).order(:id)
where(channel_hash: channel_hashes_for(channels)).
where(id: (last_id + 1)..).order(:id)
}

class << self
def broadcast(channel, payload)
attrs =
new(channel:, payload:, channel_hash: channel_hash_for(channel)).
attributes.
with_indifferent_access.except(:id, :created_at, :updated_at)

insert(attrs)
end

def channel_hashes_for(channels)
channels.map { |channel| channel_hash_for(channel) }
end

# Need to unpack this as a signed integer since Postgresql and SQLite
# don't support unsigned integers
def channel_hash_for(channel)
Digest::SHA256.digest(channel.to_s).unpack1("q>")
end
end
end
end
2 changes: 1 addition & 1 deletion lib/action_cable/subscription_adapter/solid_cable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(*)
end

def broadcast(channel, payload)
::SolidCable::Message.insert({ channel:, payload: })
::SolidCable::Message.broadcast(channel, payload)
end

def subscribe(channel, callback, success_callback = nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

ActiveRecord::Schema[7.1].define(version: 1) do
create_table "solid_cable_messages", force: :cascade do |t|
t.text "channel"
t.text "payload"
t.binary "channel", limit: 1024, null: false
t.binary "payload", limit: 536870912, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["channel"], name: "index_solid_cable_messages_on_channel",
length: 500
t.integer "channel_hash", limit: 8, null: false
t.index ["channel"], name: "index_solid_cable_messages_on_channel"
t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash"
t.index ["created_at"], name: "index_solid_cable_messages_on_created_at"
end
end
8 changes: 8 additions & 0 deletions lib/generators/solid_cable/update/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Description:
Updates Solid Cable migrations

Example:
bin/rails generate solid_cable:update

This will perform the following:
Installs new Solid Cable migrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class CreateCompactChannel < ActiveRecord::Migration[7.2]
def change
change_column :solid_cable_messages, :channel,
:binary, limit: 1024, null: false
add_column :solid_cable_messages, :channel_hash,
:integer, limit: 8, null: false
add_index :solid_cable_messages, :channel_hash
change_column :solid_cable_messages, :payload,
:binary, limit: 536_870_912, null: false
end
end
10 changes: 10 additions & 0 deletions lib/generators/solid_cable/update/update_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class SolidCable::UpdateGenerator < Rails::Generators::Base
source_root File.expand_path("templates", __dir__)

def copy_files
migration_template "db/migrate/create_compact_channel",
"db/cable_migrate/create_compact_channel"
end
end
4 changes: 4 additions & 0 deletions lib/tasks/solid_cable_tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ namespace :solid_cable do
task :install do
Rails::Command.invoke :generate, ["solid_cable:install"]
end

task :update do
Rails::Command.invoke :generate, ["solid_cable:update"]
end
end

This file was deleted.

This file was deleted.

8 changes: 5 additions & 3 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2024_08_23_212658) do
ActiveRecord::Schema[7.2].define(version: 2024_09_12_130854) do
create_table "solid_cable_messages", force: :cascade do |t|
t.text "channel"
t.text "payload"
t.binary "channel", limit: 1024, null: false
t.binary "payload", limit: 536870912, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "channel_hash", limit: 8, null: false
t.index ["channel"], name: "index_solid_cable_messages_on_channel"
t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash"
t.index ["created_at"], name: "index_solid_cable_messages_on_created_at"
end
end

0 comments on commit 7d66d87

Please sign in to comment.