与Google Photos API的竞争条件

时间:2020-08-06 07:39:03

标签: go concurrency goroutine

我正在开发this CLI,以将图像上传到Google相册。 CLI创建了几个go例程,以并行1上载文件。上载后,相同的例程会将其添加到Album中。如果这些相册在2之前不存在,则会创建它们。

由于并发性和 Google Photos API允许创建两个具有相同名称的Albums 的事实,我要避免使用重复的相册名称

GetOrCreateAlbumByName() 3不能确保Album是唯一的。它基本上询问是否存在同名专辑,如果不存在,它将创建一个新专辑。但是可以并行调用此函数,因此可以创建两个具有相同名称的Album。除了实现互斥锁外,我还在观察重复项。

您将如何建议您解决?

  1. 创建一个处理相册创建的工作程序(如微服务)。在创建专辑之前,每个执行例程都会被阻止。它将删除Album创建部分的并发性。
  2. 维护一个相册缓存,并使用它来检查相册是否已创建。在这种情况下,种族条件也可能发生,但发生的可能性较小。
  3. 一起使用1和2。
  4. 其他,请具体说明。

我对1、2和3感到担忧...这就是为什么我想知道你将如何处理它。

预先感谢

1 个答案:

答案 0 :(得分:0)

您使用Client.GetOrCreateAlbumByName()来获取或创建相册。此方法可安全地并发使用,并且在内部使用互斥锁来序列化调用,从而确保不创建重复项。

但是,您正在创建并使用多个客户端here,这意味着对所有客户端的并发调用不会序列化,而仅对单个客户端的并发调用。

因此,使用单个客户端的解决方案将对所有调用进行序列化,或者如果不可能,则必须对所有客户端的调用进行序列化,例如使用单个互斥或其他方式。

如何使用互斥锁序列化对所有客户端的呼叫的示例:

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)