func createParents(path string) error { parts := strings.Split(path, "/") pth := "" for _, p := range parts[1:] { pth += "/" + p _, err := zookeeper.Create(pth, []byte{}, 0, gozk.WorldACL(gozk.PermAll)) if err != nil && err != gozk.ErrNodeExists { return err } } return nil }
// Reserve will reserve an item with the id in the DefaultReservation for the given amount of // time. func (dr *DefaultReservation) Reserve(d time.Duration) error { log.Debugf("[Sync:Reservation] Attempting to reserve '%s' for %s...", dr.id, d) lockpath := constructPath(dr.path, dr.id) // Check if the reservation already exists b, _, err := zookeeper.Get(lockpath) if err == nil { // It exists, check if expired var expired time.Time expired.GobDecode(b) log.Debugf("[Sync:Reservation] Read existing node for '%s', expires at %s", dr.id, expired) if expired.Before(time.Now()) { log.Debugf("[Sync:Reservation] Deleting expired lock '%s'", dr.id) // It has expired, delete the node and get the reservation as usual zookeeper.Delete(lockpath, -1) } else { return ErrReserved } } expires := time.Now().Add(d) expiresBytes, err := expires.GobEncode() if err != nil { return err } for { _, err = zookeeper.Create(lockpath, expiresBytes, 0, dr.acl) if err == gozk.ErrNoNode { createParents(dr.path) } else if err == nil { break } else { log.Warnf("[Reservation] ZK error creating ephemeral lock node for reservation: %v", err) return err } } log.Debugf("[Sync:Reservation] Created lock node for '%s', expires at %s", dr.id, expires) return nil }