shad-go/keylock/README.md

47 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# keylock
Напишите примитив синхронизации, позволяющий "лочить" строки из множества.
В обычном `sync.Mutex` лок всего один. В один момент времени этот лок может находиться
у одной горутины. В нашем примитиве локов может быть сколько угодно. Каждый лок мы идентифицируем
ключом - строкой. Каждая горутина приходит к нам со списком ключей и хочет захватить сразу
все локи из этого списка. (Наша аналогия с `sync.Mutex` вовсе не значит, что нужно использовать
`sync.Mutex` в реализации. Лучше использовать каналы, чтобы проще было реализовать отмену.)
В итоге, внутри критической секции может быть сколько угодно горутин, но у всех них множества
ключей попарно не пересекаются.
Например, если к нам придёт 3 горутины:
1. `LockKeys({a, b})`
2. `LockKeys({b})`
3. `LockKeys({c})`
То в критической секции одновременно могут находиться:
* 1 и 3
* 2 и 3
А вот 1 и 2 одновременно в критическую секцию зайти не могут, потому что у них множества ключей пересекаются.
Метод `LockKeys` должен блокироваться, пока не удастся
захватить все ключи, либо пока операция не будет
отменена через канал `cancel`.
```go
package keylock
type KeyLock interface {
// LockKeys locks all keys from provided set.
//
// Upon successful completion, function guarantees that no other call with intersecting set of keys
// will finish, until unlock() is called.
//
// If cancel channel is closed, function stops trying to lock received keys and returns immediately
LockKeys(keys []string, cancel <-chan struct{}) (canceled bool, unlock func())
}
```
Реализация не должна содержать busy wait. То есть, если вызов LockKeys не может выполниться,
потому что какие-то из ключей залочены другими горутинами, то текущая горутина
должна засыпать.