mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
[Fix #28751] Hash stream long stream identifiers when using Postgres adapter
This commit is contained in:
parent
c8ce345964
commit
2bce7777b7
3 changed files with 31 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
* Hash long stream identifiers when using Postgres adapter.
|
||||
|
||||
PostgreSQL has a limit on identifiers length (63 chars, [docs](https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS)).
|
||||
Provided fix minifies identifiers longer than 63 chars by hashing them with SHA1.
|
||||
|
||||
Fixes #28751.
|
||||
|
||||
*Vladimir Dementyev*
|
||||
|
||||
* ActionCable's `redis` adapter allows for other common redis-rb options (`host`, `port`, `db`, `password`) in cable.yml.
|
||||
|
||||
Previously, it accepts only a [redis:// url](https://www.iana.org/assignments/uri-schemes/prov/redis) as an option.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
gem "pg", "~> 0.18"
|
||||
require "pg"
|
||||
require "thread"
|
||||
require "digest/sha1"
|
||||
|
||||
module ActionCable
|
||||
module SubscriptionAdapter
|
||||
|
@ -12,16 +13,16 @@ module ActionCable
|
|||
|
||||
def broadcast(channel, payload)
|
||||
with_connection do |pg_conn|
|
||||
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel)}, '#{pg_conn.escape_string(payload)}'")
|
||||
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel_identifier(channel))}, '#{pg_conn.escape_string(payload)}'")
|
||||
end
|
||||
end
|
||||
|
||||
def subscribe(channel, callback, success_callback = nil)
|
||||
listener.add_subscriber(channel, callback, success_callback)
|
||||
listener.add_subscriber(channel_identifier(channel), callback, success_callback)
|
||||
end
|
||||
|
||||
def unsubscribe(channel, callback)
|
||||
listener.remove_subscriber(channel, callback)
|
||||
listener.remove_subscriber(channel_identifier(channel), callback)
|
||||
end
|
||||
|
||||
def shutdown
|
||||
|
@ -41,6 +42,10 @@ module ActionCable
|
|||
end
|
||||
|
||||
private
|
||||
def channel_identifier(channel)
|
||||
channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
|
||||
end
|
||||
|
||||
def listener
|
||||
@listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) }
|
||||
end
|
||||
|
|
|
@ -112,4 +112,18 @@ module CommonSubscriptionAdapterTest
|
|||
assert_equal "two", queue.pop
|
||||
end
|
||||
end
|
||||
|
||||
def test_long_identifiers
|
||||
channel_1 = "a" * 100 + "1"
|
||||
channel_2 = "a" * 100 + "2"
|
||||
subscribe_as_queue(channel_1) do |queue|
|
||||
subscribe_as_queue(channel_2) do |queue_2|
|
||||
@tx_adapter.broadcast(channel_1, "apples")
|
||||
@tx_adapter.broadcast(channel_2, "oranges")
|
||||
|
||||
assert_equal "apples", queue.pop
|
||||
assert_equal "oranges", queue_2.pop
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue