class ActionCable::Server::Base
A singleton ActionCable::Server
instance is available via ActionCable.server
. It's used by the Rack process that starts the Action Cable server, but is also used by the user to reach the RemoteConnections
object, which is used for finding and disconnecting connections across all servers.
Also, this is the server instance used for broadcasting. See Broadcasting
for more information.
Attributes
Public Class Methods
# File lib/action_cable/server/base.rb, line 17 def self.logger; config.logger; end
# File lib/action_cable/server/base.rb, line 22 def initialize @mutex = Monitor.new @remote_connections = @event_loop = @worker_pool = @pubsub = nil end
Public Instance Methods
Called by Rack to setup the server.
# File lib/action_cable/server/base.rb, line 28 def call(env) setup_heartbeat_timer config.connection_class.call.new(self, env).process end
All of the identifiers applied to the connection class associated with this server.
# File lib/action_cable/server/base.rb, line 82 def connection_identifiers config.connection_class.call.identifiers end
Disconnect all the connections identified by identifiers
on this server or any others via RemoteConnections
.
# File lib/action_cable/server/base.rb, line 34 def disconnect(identifiers) remote_connections.where(identifiers).disconnect end
# File lib/action_cable/server/base.rb, line 57 def event_loop @event_loop || @mutex.synchronize { @event_loop ||= ActionCable::Connection::StreamEventLoop.new } end
Adapter used for all streams/broadcasting.
# File lib/action_cable/server/base.rb, line 77 def pubsub @pubsub || @mutex.synchronize { @pubsub ||= config.pubsub_adapter.new(self) } end
Gateway to RemoteConnections
. See that class for details.
# File lib/action_cable/server/base.rb, line 53 def remote_connections @remote_connections || @mutex.synchronize { @remote_connections ||= RemoteConnections.new(self) } end
# File lib/action_cable/server/base.rb, line 38 def restart connections.each(&:close) @mutex.synchronize do # Shutdown the worker pool @worker_pool.halt if @worker_pool @worker_pool = nil # Shutdown the pub/sub adapter @pubsub.shutdown if @pubsub @pubsub = nil end end
The worker pool is where we run connection callbacks and channel actions. We do as little as possible on the server's main thread. The worker pool is an executor service that's backed by a pool of threads working from a task queue. The thread pool size maxes out at 4 worker threads by default. Tune the size yourself with config.action_cable.worker_pool_size
.
Using Active Record, Redis, etc within your channel actions means you'll get a separate connection from each thread in the worker pool. Plan your deployment accordingly: 5 servers each running 5 Puma workers each running an 8-thread worker pool means at least 200 database connections.
Also, ensure that your database connection pool size is as least as large as your worker pool size. Otherwise, workers may oversubscribe the database connection pool and block while they wait for other workers to release their connections. Use a smaller worker pool or a larger database connection pool instead.
# File lib/action_cable/server/base.rb, line 72 def worker_pool @worker_pool || @mutex.synchronize { @worker_pool ||= ActionCable::Server::Worker.new(max_size: config.worker_pool_size) } end