Exemple #1
0
// sequentialFight returns the path to the lock with the lowest sequence number.
// If that file is the same the one passed it returns nil meaning that that sequence
// number has win the fight, if not it will return ErrLockFound.
func sequentialFight(client *ezk.Client, base string, seq int) (string, error) {
	// Read all the childrens
	children, _, err := client.Children(base)
	if err != nil {
		return "", err
	}

	// Look for the lowest sequence number
	var lowestNode string
	lowestSeq := seq
	for _, p := range children {
		s, err := parseSeq(p)
		// ignore unknown znodes
		if err == nil {
			if s < lowestSeq {
				lowestSeq = s
				lowestNode = p
			}
		}
	}

	// Add the base path
	lowestNode = join(base, lowestNode)

	// Acquire the lock
	if seq == lowestSeq {
		return lowestNode, nil
	}

	return lowestNode, ErrLockFound
}
Exemple #2
0
// timeBasedCleaner deletes those znodes in the base path older than t.
func timeBasedCleaner(client *ezk.Client, base string, t time.Duration) error {
	now := unixMilli()

	// Read all the childrens
	children, _, err := client.Children(base)
	if err != nil {
		return err
	}

	// Iterate to all the childrents reading the creation time
	millis := int64(t / time.Millisecond)
	for i := range children {
		node := join(base, children[i])
		ok, stat, err := client.Exists(node)
		if err != nil {
			return err
		}

		// Delete locks older than SchedulerLockTime
		if ok && stat.Ctime+millis < now {
			if err := client.Delete(node, stat.Version); err != nil && err != zk.ErrNoNode {
				return err
			}
		}
	}

	return nil
}
Exemple #3
0
// createSequentialLock creates a new lock and returns the full path of the lock.
func createSequentialLock(client *ezk.Client, base string, acl []zk.ACL) (string, error) {
	lockPath := fmt.Sprintf("%s/lock.", base)

	// Create lock attempt /base/_c_67c79fecc6104a7026bdd7c3ce773828-lock.0000000001
	return client.CreateProtectedEphemeralSequential(lockPath, nil, acl)
}