feat(counter): add Mozo::Counter.provision! to seed Redis from CouchDB

- Reads Order.by_supplier_id_and_state view (reduce, grouped)
- Sets Redis keys: supplier_counter:<id>:orders_placed / orders_in_process
- Creates design doc if missing (from drb_counter/couchdb_design.yml)
- Rake task: rails counters:provision
- Also invokable directly: rails runner 'Mozo::Counter.provision!'
This commit is contained in:
BenClaw
2026-05-17 22:02:56 +02:00
parent 686dc65b9c
commit eef3d17431
2 changed files with 57 additions and 0 deletions
+52
View File
@@ -23,5 +23,57 @@ module Mozo
options[:initial] ||= 0
connection.decr(key, options) rescue 0
end
# Provision Redis counters from CouchDB aggregated data.
# Reads the Order.by_supplier_id_and_state view (reduce, grouped),
# and sets the corresponding Redis keys.
#
# Invoke via: rails runner 'Mozo::Counter.provision!'
#
def self.provision!
require 'couchrest'
db = Order.database
design = '_design/order_counter'
view = 'by_supplier_id_and_state'
# Ensure the design doc exists
unless db.get(design) rescue nil
puts "[Counter.provision!] Creating design doc #{design}"
doc = YAML.safe_load(
File.read(Rails.root.join('drb_counter/couchdb_design.yml')),
permitted_classes: [Symbol]
)
doc['_id'] = design
doc['language'] ||= 'javascript'
db.save_doc(doc)
end
# Query with reduce + group to get per-supplier/per-state counts
result = db.view("#{design}/_view/#{view}", reduce: true, group: true, group_level: 2)
rows = result['rows'] || []
puts "[Counter.provision!] #{rows.size} counter keys to set"
rows.each do |row|
supplier_id, state = row['key']
count = row['value']
case state
when 'placed'
key = "supplier_counter:#{supplier_id}:orders_placed"
when 'active'
key = "supplier_counter:#{supplier_id}:orders_in_process"
else
next
end
set(key, count)
puts " #{key} = #{count}"
end
puts "[Counter.provision!] Done."
rows.size
end
end
end