feat(broadcasting): add ActionCable adapter + fix model broadcast anti-pattern
- Add Mozo::Broadcaster::ActionCable as drop-in Faye replacement - Fix model_broadcast.rb: delegate to Mozo directly instead of ApplicationController.new (memory-unsafe anti-pattern) - Add Broadcastable concern for clean model-side broadcasting - ActionCable config: async adapter, cable.yml, WebSocket endpoint - MozoChannel with per-entity authorization (user/supplier/employee) - Connection auth via auth_token (matches existing auth pattern) - Mount /cable WebSocket in routes - Add broadcasting-migration.md with Faye→ActionCable guide
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# ActionCable configuration for real-time broadcasting.
|
||||
#
|
||||
# Development/Test: async adapter (in-process, no external dependency).
|
||||
# Production: async is fine for single-server deployments.
|
||||
# Switch to Redis (`redis://...`) if scaling to multiple Puma workers
|
||||
# where broadcasts need to reach clients connected to different workers.
|
||||
#
|
||||
development:
|
||||
adapter: async
|
||||
|
||||
test:
|
||||
adapter: test
|
||||
|
||||
production:
|
||||
adapter: async
|
||||
# adapter: redis
|
||||
# url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
|
||||
# channel_prefix: mozo_backend_production
|
||||
@@ -1,12 +1,31 @@
|
||||
#TODO: this is really ugly, can cause memory leaks and much more bad stuff. We need a new broadcaster....
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Broadcast shim: provides broadcast_supplier / broadcast_user to all
|
||||
# SimplyStored::Couch models without requiring ApplicationController.new.
|
||||
#
|
||||
# PREVIOUSLY (dangerous):
|
||||
# ApplicationController.new.send(:broadcast_supplier, *args)
|
||||
# → leaked controller instances, no request lifecycle
|
||||
#
|
||||
# NOW:
|
||||
# Delegates directly to Mozo.broadcast_supplier / Mozo.broadcast_user
|
||||
# which uses Mozo.broadcaster (configurable: Faye or ActionCable).
|
||||
#
|
||||
# MIGRATION PATH:
|
||||
# Models should `include Broadcastable` directly instead of relying
|
||||
# on this monkey-patch. Once all models include Broadcastable, this
|
||||
# initializer can be removed.
|
||||
#
|
||||
require 'simply_stored/couch'
|
||||
|
||||
module ModelBroadcast
|
||||
def broadcast_supplier(*args)
|
||||
ApplicationController.new.send(:broadcast_supplier, *args)
|
||||
def broadcast_supplier(sid, event, data = {})
|
||||
Mozo.broadcast_supplier(sid, event, data)
|
||||
end
|
||||
def broadcast_user(*args)
|
||||
ApplicationController.new.send(:broadcast_user, *args)
|
||||
|
||||
def broadcast_user(uid, event, data = {})
|
||||
Mozo.broadcast_user(uid, event, data)
|
||||
end
|
||||
end
|
||||
|
||||
SimplyStored::Couch.send(:include, ModelBroadcast)
|
||||
#SimplyStored::Couch.send(:extend, ModelBroadcast) # this should never happen!!!
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
ALLOWED_LOCALES = /nl|de|fr|en|es/
|
||||
Mozo::Application.routes.draw do
|
||||
# ActionCable WebSocket endpoint (replaces Faye at events.mozo.bar/faye)
|
||||
# Clients connect via: wss://mozo.bar/cable?auth_token=TOKEN
|
||||
mount ActionCable.server => '/cable'
|
||||
|
||||
match '/.well-known/*rest', to: 'errors#not_found', via: :all
|
||||
match '/system/*rest', to: 'errors#not_found', via: :all
|
||||
devise_for :users, controllers: {
|
||||
|
||||
Reference in New Issue
Block a user