Состояние гонки против API Google Фото - PullRequest
1 голос
/ 06 августа 2020

Я разрабатываю этот CLI для загрузки изображений в Google Фото. CLI создает несколько go подпрограмм для параллельной загрузки файлов 1 . После загрузки та же процедура добавляет его к Album. Эти альбомы создаются, если они не существовали раньше. 2 .

Из-за параллелизма и того факта, что API Google Фото позволяет создавать два Albums с одинаковыми name , у меня есть повторяющиеся названия альбомов, которых я бы хотел избежать.

GetOrCreateAlbumByName() 3 не гарантирует, что Album уникален. Он в основном спрашивает, существует ли альбом с таким же именем, и если нет, он создаст новый. Но эта функция может быть вызвана параллельно, поэтому могут быть созданы два Album с одинаковым именем. Помимо реализации мьютекса, я наблюдаю за дубликатами.

Как вы порекомендуете с этим справиться?

  1. Создайте воркер (например, микросервис) которые занимаются созданием альбомов. Каждая подпрограмма go будет заблокирована, пока не будет создан альбом. Он удалит параллелизм в части создания Album.
  2. Поддерживайте кеш-память альбома и используйте его, чтобы проверить, был ли альбом уже создан. В этом случае также может произойти состояние гонки, но с меньшей вероятностью.
  3. Использование 1 и 2 вместе.
  4. Другое, укажите.

У меня есть вопросы примерно 1, 2 и 3 ... вот почему я хотел бы знать, как вы с этим справитесь.

Заранее спасибо

1 Ответ

0 голосов
/ 07 августа 2020

Вы используете Client.GetOrCreateAlbumByName() для получения или создания альбомов. Этот метод безопасен для одновременного использования, и он использует внутреннее мьютекс для сериализации вызовов, что гарантирует, что дубликаты не будут созданы.

Однако вы создаете и используете несколько клиентов здесь , что означает одновременные вызовы для всех из них не сериализуются, а только параллельные вызовы отдельным клиентам. вызовы всем клиентам, например, с использованием одного мьютекса или других средств.

Пример того, как сериализовать вызовы всем клиентам с помощью мьютекса:

var mu sync.Mutex

func GetOrCreateAlbumByName(c *gphotos.Client, name string) (*photoslibrary.Album, error) {
    mu.Lock()
    defer mu.Unlock()
    return c.GetOrCreateAlbumByName(name)
}

И где бы вы ни использовали client.GetOrCreateAlbumByName(name), замените его на звонок:

GetOrCreateAlbumByName(client, name)
...