package main import ( "context" "log" "sync" "git.k6n.net/mats/go-redis-inventory/pkg/inventory" "git.k6n.net/mats/platform/rabbit" "git.k6n.net/mats/slask-finder/pkg/types" "github.com/redis/go-redis/v9" ) type StockHandler struct { rdb *redis.Client ctx context.Context svc inventory.RedisInventoryService MainStockLocationID inventory.LocationID // Bus producer config. conn is nil when RABBIT_HOST is unset (no bus); the // handler still updates Redis and just skips emitting. conn *rabbit.Conn country string low int64 } func (s *StockHandler) HandleItem(item types.Item, wg *sync.WaitGroup) { wg.Go(func() { ctx := s.ctx centralStock, ok := item.GetNumberFieldValue("inStock") if !ok { centralStock = 0 } sku, ok := item.GetStringFieldValue("sku") if !ok { log.Printf("unable to parse central stock for item: sku missing") return } // One linear pass: write the authoritative quantity, then derive and // emit the level crossing from the same value. No Redis pub/sub // round-trip — Redis stays the internal store, the bus carries levels. pipe := s.rdb.Pipeline() s.svc.UpdateInventory(ctx, pipe, inventory.SKU(sku), s.MainStockLocationID, int64(centralStock)) if _, err := pipe.Exec(ctx); err != nil { log.Printf("unable to update stock: %v", err) return } emitLevelIfChanged(ctx, s.rdb, s.conn, s.country, s.low, sku, string(s.MainStockLocationID), int64(centralStock)) }) }