func validateClaimedEvents() { log.L.Debug("validating claimed events") queueNames := db.AllQueueNames() for i := range queueNames { queueName := queueNames[i] claimedKey := db.ClaimedKey(queueName) // get the presumably oldest 50 items var eventIDs []string eventIDs, err := db.Inst.Cmd("LRANGE", claimedKey, -50, -1).List() if err != nil { log.L.Printf("ERR lrange redis replied %q", err) return } else if len(eventIDs) == 0 { continue } var locks []interface{} for i := range eventIDs { lockKey := db.ItemLockKey(queueName, eventIDs[i]) locks = append(locks, lockKey) } var locksList [][]byte locksList, err = db.Inst.Cmd("MGET", locks...).ListBytes() if err != nil { log.L.Printf("ERR mget redis replied %q", err) return } for i := range locksList { if locksList[i] == nil { err = restoreEventToQueue(queueName, eventIDs[i]) if err != nil { return } } } } }
func qack(client *clients.Client, args []string) (interface{}, error) { queueName, eventID := args[0], args[1] claimedKey := db.ClaimedKey(queueName) var numRemoved int numRemoved, err := db.Inst.Cmd("LREM", claimedKey, -1, eventID).Int() if err != nil { return nil, fmt.Errorf("QACK LREM (claimed): %s", err) } // If we didn't removed the eventID from the claimed events we see if it can // be found in unclaimed. We only do this in the uncommon case that the // eventID isn't in claimed since unclaimed can be really large, so LREM is // slow on it if numRemoved == 0 { unclaimedKey := db.UnclaimedKey(queueName) var err error numRemoved, err = db.Inst.Cmd("LREM", unclaimedKey, -1, eventID).Int() if err != nil { return nil, fmt.Errorf("QACK LREM (unclaimed): %s", err) } } // We only remove the object data itself if the eventID was actually removed // from something if numRemoved > 0 { itemsKey := db.ItemsKey(queueName) lockKey := db.ItemLockKey(queueName, eventID) _, err := db.Inst.Pipe( db.PP("HDEL", itemsKey, eventID), db.PP("DEL", lockKey), ) if err != nil { return nil, fmt.Errorf("QACK HDEL/DEL: %s", err) } } return numRemoved, nil }