From eef3d17431e4033d0f4c491dc084dfe7bd3b491d Mon Sep 17 00:00:00 2001 From: BenClaw Date: Sun, 17 May 2026 22:02:56 +0200 Subject: [PATCH] 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::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!' --- lib/mozo/counter.rb | 52 +++++++++++++++++++++++++++++++++++++++++ lib/tasks/counters.rake | 5 ++++ 2 files changed, 57 insertions(+) diff --git a/lib/mozo/counter.rb b/lib/mozo/counter.rb index 5f3c775e..d5c0ac15 100644 --- a/lib/mozo/counter.rb +++ b/lib/mozo/counter.rb @@ -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 diff --git a/lib/tasks/counters.rake b/lib/tasks/counters.rake index 5f02eba5..16abbede 100644 --- a/lib/tasks/counters.rake +++ b/lib/tasks/counters.rake @@ -2,4 +2,9 @@ namespace :counters do task reset: :environment do Supplier.reset_counters! end + + desc 'Provision Redis counters from CouchDB aggregated data' + task provision: :environment do + Mozo::Counter.provision! + end end