Subscription adapters provide pluggable pub/sub backends for scaling ActionCable across multiple server processes and machines. ActionCable ships with several built-in adapters for different deployment scenarios.
Abstract base class defining the interface all subscription adapters must implement.
class ActionCable::SubscriptionAdapter::Base
def initialize(server)
end
# Broadcast message to a channel
# @param channel [String] Channel name to broadcast to
# @param payload [String] JSON-encoded message payload
def broadcast(channel, payload)
raise NotImplementedError
end
# Subscribe to a channel
# @param channel [String] Channel name to subscribe to
# @param message_callback [Proc] Callback for received messages
# @param success_callback [Proc] Optional success callback
def subscribe(channel, message_callback, success_callback = nil)
raise NotImplementedError
end
# Unsubscribe from a channel
# @param channel [String] Channel name to unsubscribe from
# @param message_callback [Proc] Message callback to remove
def unsubscribe(channel, message_callback)
raise NotImplementedError
end
# Shutdown the adapter and cleanup resources
def shutdown
raise NotImplementedError
end
attr_reader :logger, :server
endProduction-ready adapter using Redis for pub/sub across multiple servers.
class ActionCable::SubscriptionAdapter::Redis < ActionCable::SubscriptionAdapter::Base
def initialize(server)
super
end
# Broadcast message via Redis PUBLISH
def broadcast(channel, payload)
end
# Subscribe to Redis channel
def subscribe(channel, message_callback, success_callback = nil)
end
# Unsubscribe from Redis channel
def unsubscribe(channel, message_callback)
end
# Shutdown Redis connections
def shutdown
end
endConfiguration Example:
# config/cable.yml
production:
adapter: redis
url: redis://localhost:6379/1
channel_prefix: myapp_production
# Or with Redis connection options
production:
adapter: redis
url: redis://user:password@redis.example.com:6380/0
channel_prefix: myapp_production
timeout: 1Database-backed adapter using PostgreSQL's LISTEN/NOTIFY for pub/sub.
class ActionCable::SubscriptionAdapter::PostgreSQL < ActionCable::SubscriptionAdapter::Base
def initialize(server)
super
end
# Broadcast via PostgreSQL NOTIFY
def broadcast(channel, payload)
end
# Subscribe via PostgreSQL LISTEN
def subscribe(channel, message_callback, success_callback = nil)
end
# Unsubscribe via PostgreSQL UNLISTEN
def unsubscribe(channel, message_callback)
end
# Shutdown PostgreSQL connections
def shutdown
end
endConfiguration Example:
# config/cable.yml
production:
adapter: postgresql
url: postgresql://user:password@localhost/myapp_production
channel_prefix: myapp_productionIn-memory adapter using concurrent-ruby for single-server deployments.
class ActionCable::SubscriptionAdapter::Async < ActionCable::SubscriptionAdapter::Base
def initialize(server)
super
end
# Broadcast to in-memory subscribers
def broadcast(channel, payload)
end
# Subscribe to in-memory channel
def subscribe(channel, message_callback, success_callback = nil)
end
# Unsubscribe from in-memory channel
def unsubscribe(channel, message_callback)
end
# Shutdown async executor
def shutdown
end
endConfiguration Example:
# config/cable.yml
development:
adapter: async
test:
adapter: testSynchronous adapter for testing - executes callbacks immediately.
class ActionCable::SubscriptionAdapter::Inline < ActionCable::SubscriptionAdapter::Base
def initialize(server)
super
end
# Broadcast immediately to subscribers
def broadcast(channel, payload)
end
# Subscribe immediately
def subscribe(channel, message_callback, success_callback = nil)
end
# Unsubscribe immediately
def unsubscribe(channel, message_callback)
end
# No-op shutdown
def shutdown
end
endAdds channel prefixing capabilities to adapters.
module ActionCable::SubscriptionAdapter::ChannelPrefix
private
# Add configured prefix to channel name
# @param channel [String] Base channel name
# @return [String] Prefixed channel name
def channel_with_prefix(channel)
end
# Get channel prefix from configuration
# @return [String] Configured channel prefix
def channel_prefix
end
endManages subscription mappings for adapters.
class ActionCable::SubscriptionAdapter::SubscriberMap
def initialize
end
# Add subscription
# @param channel [String] Channel name
# @param callback [Proc] Message callback
def add_subscription(channel, callback)
end
# Remove subscription
# @param channel [String] Channel name
# @param callback [Proc] Message callback to remove
def remove_subscription(channel, callback)
end
# Get callbacks for channel
# @param channel [String] Channel name
# @return [Array<Proc>] Array of callbacks
def broadcast(channel, message)
end
# Remove all subscriptions for channel
# @param channel [String] Channel name
def remove_channel(channel)
end
endAccessing and configuring the subscription adapter.
class ActionCable::Server::Base
# Get the configured pubsub adapter instance
def pubsub
@pubsub ||= config.pubsub_adapter.new(self)
end
attr_reader :config
end
class ActionCable::Server::Configuration
# Subscription adapter class (defaults to Async)
attr_accessor :pubsub_adapter
# Adapter-specific configuration
attr_accessor :cable
endUsage Examples:
# Get current adapter
adapter = ActionCable.server.pubsub
# => #<ActionCable::SubscriptionAdapter::Redis:0x...>
# Access configuration
config = ActionCable.server.config
puts config.cable[:adapter]
# => "redis"
# Manual adapter configuration
ActionCable.server.config.pubsub_adapter = ActionCable::SubscriptionAdapter::PostgreSQLActionCable automatically selects adapters based on configuration:
# config/cable.yml determines adapter
development:
adapter: async # Uses Async adapter
test:
adapter: test # Uses Inline adapter
production:
adapter: redis # Uses Redis adapter
url: redis://localhost:6379/1Creating custom subscription adapters:
class CustomAdapter < ActionCable::SubscriptionAdapter::Base
def broadcast(channel, payload)
# Custom broadcasting logic
end
def subscribe(channel, message_callback, success_callback = nil)
# Custom subscription logic
end
def unsubscribe(channel, message_callback)
# Custom unsubscription logic
end
def shutdown
# Custom cleanup logic
end
end
# Configure custom adapter
ActionCable.server.config.pubsub_adapter = CustomAdapter