treelock

package module
v0.0.0-...-bde644e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2018 License: MIT Imports: 2 Imported by: 1

README

TreeLock

TreeLock is a tree-based locking mechanism in the Go Programming Language. It acts similar to sync.Mutex, but instead locks on a name-by-name basis, basically a map[string]sync.Mutex, with some additional features:

  • Hierarchical locking: Using arrays of strings to lock sub-values. Locking []string{"a", "b"} will lock any string array that starts with []string{"a", "b"}, such as []string{"a", "b", "c"}. So, if you want to edit a single element of use "argusdusty", you could run treelock.Lock([]string{"users", "argusdusty", "element"}), and another thread could still lock []string{"users", "argusdusty", "element2"} without waiting for the first to finish, but if another wanted to gain control over the whole object it could lock []string{"users, "argusdusty"}, which would wait for any existing threads using the "argusdusty" user to finish, then would block any future threads from using that user until unlocked.

  • Locking multiple strings simultaneously: If a thread wanted to lock objects named "a" and "b", you could try locking "a", then "b", but another thread could lock "b", then "a" leading to a potential deadlock. treelock has LockMany, which will avoid a deadlock by sorting the incoming values beforehand, so now you just run treelock.LockMany([]string{"a"}, []string{"b"}) or treelock.LockMany([]string{"b"}, []string{"a"}) and, of course treelock.UnlockMany([]string{"a"}, []string{"b"}) and you don't have to worry about potential deadlock conditions.

This allows you to minimize overhead in asynchronous access to a large number of distinct objects, without fear of two threads undoing each other.

Examples

  • Lock all users: treelock.Lock([]string{"users"})
  • Lock a single user named "argusdusty": treelock.Lock([]string{"users", "argusdusty"})
  • Lock two users named "1234" and "asdf": treelock.LockMany([]string{"users", "1234"}, []string{"users", "asdf"})
  • Lock all users: treelock.LockMany([]string{"users"})
  • Lock everything: treelock.LockAll()
SimpleTreeLock

The SimpleTreeLock structure is the same as TreeLock, except limited to depth=1, so it's more of a MapLock:

  • Lock a single item: simpletreelock.Lock("asdf")
  • Lock multiple items: simpletreelock.LockMany("asdf", "1234")
  • Lock everything: simpletreelock.LockAll()
Attribution

This code was developed for Tamber, Inc. (www.tamber.com), and is used in the backend for the Tamber Concerts app to optimize data manipulation while ensuring thread safety over arbitrarily defined collections of data.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var MutexGenerator func(path []string) sync.Locker = func(path []string) sync.Locker { return new(sync.Mutex) }

Global function supporting custom Mutex/WaitGroup generators. For example, allowing global treeLocks by handling locks through a database. Or alternatively, enabling callbacks when locking/unlocking occurs

View Source
var WaitGroupGenerator func(path []string) WaitGroup = func(path []string) WaitGroup { return new(sync.WaitGroup) }

Functions

This section is empty.

Types

type SimpleTreeLock

type SimpleTreeLock struct {
	// contains filtered or unexported fields
}

func NewSimpleTreeLock

func NewSimpleTreeLock() *SimpleTreeLock

Equivalent to a TreeLock restricted to depth=1

func (*SimpleTreeLock) Lock

func (T *SimpleTreeLock) Lock(val string)

func (*SimpleTreeLock) LockAll

func (T *SimpleTreeLock) LockAll()

func (*SimpleTreeLock) LockMany

func (T *SimpleTreeLock) LockMany(vals ...string)

func (*SimpleTreeLock) Unlock

func (T *SimpleTreeLock) Unlock(val string)

func (SimpleTreeLock) UnlockAll

func (T SimpleTreeLock) UnlockAll()

func (*SimpleTreeLock) UnlockMany

func (T *SimpleTreeLock) UnlockMany(vals ...string)

type Sorter

type Sorter [][]string

func (Sorter) Less

func (S Sorter) Less(i, j int) bool

type TreeLock

type TreeLock struct {
	// contains filtered or unexported fields
}

func NewTreeLock

func NewTreeLock() *TreeLock

Create a new tree lock

func (*TreeLock) Lock

func (T *TreeLock) Lock(val []string)

Safely lock a value to prevent threads from accessing this value

func (*TreeLock) LockAll

func (T *TreeLock) LockAll()

Lock the entire tree, waits for all existing locks to unlock first.

func (*TreeLock) LockMany

func (T *TreeLock) LockMany(vals ...[]string)

Safely lock multiple values simultaneously while preventing race condition Use this if the same thread will need to have multiple values locked Attempting to lock overlapping values will deadlock

func (*TreeLock) Unlock

func (T *TreeLock) Unlock(val []string)

Unlock a value to allow it to be used by another thread. Will panic if the value is not locked

func (*TreeLock) UnlockAll

func (T *TreeLock) UnlockAll()

Unlock a lock on the entire tree

func (*TreeLock) UnlockMany

func (T *TreeLock) UnlockMany(vals ...[]string)

Safely unlock multiple values simultaneously while preventing race condition

type WaitGroup

type WaitGroup interface {
	Add(delta int)
	Wait()
	Done()
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL