feat(counter): add Redis counter adapter, replace DrbCounter
- Add Mozo::Counter::Redis with same get/set/incr/decr interface - Add redis gem (~> 5.0) to Gemfile - Update cable.yml to use Redis adapter in production (shared with counters) - Document DrbCounter → Redis migration in broadcasting-migration.md - Redis installed and running on vmi3300327 - Leave Faye as current broadcaster; both switches are one-line changes DrbCounter problems solved: - In-memory → persistent (RDB + AOF) - Single-process DRb → multi-process safe Redis - Atomic INCR/DECR across Puma workers - One less custom process to manage
This commit is contained in:
@@ -87,3 +87,63 @@ Once stable:
|
||||
- **Simpler deploys** — one less service to manage
|
||||
- **WebSocket native** — no long-polling fallback complexity
|
||||
- **Rails auth** — cookies/sessions work automatically
|
||||
|
||||
---
|
||||
|
||||
# Counter: DrbCounter → Redis Migration
|
||||
|
||||
## Current state
|
||||
|
||||
```
|
||||
Supplier::Counters (app/models/supplier/counters.rb)
|
||||
→ Mozo::Counter.incr/decr/get/set
|
||||
→ Mozo::Counter.connection (Mozo::DrbCounter.object)
|
||||
→ DRb → druby://localhost:9022
|
||||
→ InMemoryQCounter (separate Ruby process)
|
||||
→ on startup: reloads counts from CouchDB
|
||||
→ in-memory only (lost on restart)
|
||||
```
|
||||
|
||||
## Problems
|
||||
|
||||
1. **In-memory only** — restart the DRb process = lose all counts until CouchDB reload
|
||||
2. **Single-process** — DRb runs one Ruby process, single point of failure
|
||||
3. **Separate process** — another thing to monitor, deploy, and restart
|
||||
4. **Race conditions** — between Puma workers, increment/decrement is not atomic across the DRb boundary
|
||||
5. **Custom code** — `InMemoryQCounter` is 100 lines of hand-rolled counter logic
|
||||
|
||||
## Target state
|
||||
|
||||
```
|
||||
Supplier::Counters
|
||||
→ Mozo::Counter.incr/decr/get/set
|
||||
→ Mozo::Counter.connection (Mozo::Counter::Redis.new)
|
||||
→ Redis (localhost:6379)
|
||||
→ persistent, atomic, multi-process safe
|
||||
```
|
||||
|
||||
## How to switch
|
||||
|
||||
In `config/initializers/mozo_settings.rb`, change:
|
||||
|
||||
```ruby
|
||||
# Mozo::Counter.connection = Mozo::DrbCounter.object # old
|
||||
Mozo::Counter.connection = Mozo::Counter::Redis.new # new
|
||||
```
|
||||
|
||||
That's it. All existing `Mozo::Counter.get/set/incr/decr` calls work unchanged.
|
||||
|
||||
## What Redis provides
|
||||
|
||||
- **Atomic INCR/DECR** — no race conditions
|
||||
- **Persistence** — RDB snapshots + AOF, survives restarts
|
||||
- **Multi-process** — all Puma workers share the same Redis
|
||||
- **Already needed** — ActionCable uses Redis for pub/sub in production
|
||||
- **Battle-tested** — millions of deployments
|
||||
|
||||
## Migration steps
|
||||
|
||||
1. `apt-get install redis-server` — already done on vmi3300327
|
||||
2. `gem 'redis', '~> 5.0'` — added to Gemfile
|
||||
3. Switch `Mozo::Counter.connection` — one-line change in mozo_settings.rb
|
||||
4. Stop the DRb counter process (`drb_counter/drb_counter.rb`)
|
||||
|
||||
Reference in New Issue
Block a user