2020-03-07 19:14:49 +00:00
|
|
|
|
# retryupdate
|
|
|
|
|
|
|
|
|
|
В этой задаче, вам нужно познакомиться с паттернами обработки ошибок в golang.
|
|
|
|
|
|
|
|
|
|
Вам дан клиент вымышленного сервиса. Сервис хранит отображение `key -> (value, version)`,
|
|
|
|
|
где `key` и `value` - это обычные строки. А `version` - уникальный идентификатор, который сгенерировал
|
|
|
|
|
клиент.
|
|
|
|
|
|
|
|
|
|
Вам доступны два метода - `Get` и `Set`. Поведение методов описано в пакете `kvapi`.
|
|
|
|
|
|
|
|
|
|
Методы могут завершаться с различными ошибками. Ошибки описаны в том же пакете.
|
|
|
|
|
|
|
|
|
|
Вам нужно реализовать функцию `UpdateValue`, которая принимает ключ и функцию
|
|
|
|
|
для "обновления" значения. Функция должна обновить значение по ключу, правильно обрабатывая
|
|
|
|
|
ошибки, возникающие в процессе работы.
|
|
|
|
|
|
|
|
|
|
- Если ключ не нашёлся, нужно передать в `updateFn` значение `nil`.
|
|
|
|
|
- Если произошла ошибка доступа, то нужно сразу выходить.
|
|
|
|
|
- Если произошла ошибка внутри updateFn, то нужно сразу выходить.
|
|
|
|
|
- Если случился конфликт при записи, и значение изменилось с момента последнего чтения,
|
|
|
|
|
то нужно прочитать новое значение и попробовать заново.
|
|
|
|
|
- Любые другие ошибки из `api` нужно "ретраить" бесконечно.
|
|
|
|
|
|
|
|
|
|
Функция должна минимизировать число запросов к API.
|
|
|
|
|
|
|
|
|
|
Для генерации нового `uuid` на клиенте, используйте вызов `uuid.Must(uuid.NewV4())`.
|
|
|
|
|
|
|
|
|
|
Большую цепочку `if`-ов удобнее писать через `switch`.
|
|
|
|
|
|
|
|
|
|
Для выхода из вложенных циклов вам помогут [loop labels](https://golang.org/doc/effective_go.html#switch).
|
2020-03-14 14:12:01 +00:00
|
|
|
|
|
|
|
|
|
Для обработки ошибок, вам потребуется использовать функции `errors.Is` и `errors.As`. Мы
|
|
|
|
|
советуем прочитать документацию и [заметку](https://blog.golang.org/go1.13-errors) в блоге,
|
|
|
|
|
перед тем как приступать к этому заданию.
|