管理长时间运行的操作

长时间运行的操作 (LRO) 是指 API 方法的完成时间长于适合 API 响应的时间。通常,您不希望在任务运行时保持调用线程处于打开状态,因为这会给用户带来糟糕的体验。相反,最好向用户返回某种类型的 promise,并允许他们稍后再回来查看。

每当您通过云端硬盘 API 或其客户端库files 资源调用 download() 方法以下载文件内容时,Google 云端硬盘 API 都会返回一个 LRO。

该方法会向客户端返回 operations 资源。您可以使用 operations 资源通过 get() 方法轮询操作,以异步检索 API 方法的状态。Drive API 中的 LRO 遵循 Google Cloud LRO 设计模式

如需了解详情,请参阅长时间运行的操作

流程概览

下图简要展示了 file.download 方法的工作步骤。

file.download 方法的概要步骤。
图 1. file.download 方法的简要步骤。

  1. 调用 files.download:当您的应用调用 download() 方法时,它会针对文件发起 Drive API 下载请求。如需了解详情,请参阅下载文件

  2. 请求权限:该请求会向 Drive API 发送身份验证凭据。如果您的应用需要使用尚未授予的用户身份验证信息调用 Drive API,则会提示用户登录。您的应用还会请求使用您在设置身份验证时指定的范围来获取访问权限。

  3. 开始下载:发出 Drive API 请求以开始下载文件。您可以针对 Google Vids 或其他 Google Workspace 内容提出此要求。

  4. 启动 LRO:开始一项长时间运行的操作,该操作会管理下载流程。

  5. 返回待处理的操作:Drive API 会返回一个待处理的操作,其中包含有关发出请求的用户的信息以及多个文件元数据字段。

  6. 初始待处理状态:您的应用会收到待处理操作以及初始待处理状态 done=null。这表示文件尚未准备好下载,并且操作状态为“待处理”。

  7. 调用 operations.get 并验证结果:您的应用会按照建议的时间间隔调用 get(),以轮询操作结果并获取长时间运行的操作的最新状态。如果返回待处理状态 done=false,您的应用必须不断轮询,直到操作返回已完成状态 (done=true)。对于大型文件,预计需要轮询多次。如需了解详情,请参阅获取长时间运行的操作的详细信息

  8. 检查待处理状态:如果 LRO 返回 done=true 的待处理状态,则表示文件已可供下载,并且操作状态为“已完成”。

  9. 返回包含下载 URI 的已完成操作:LRO 完成后,Drive API 会返回下载 URI,并且文件现在可供用户使用。

下载文件

如需在长时间运行的操作下下载内容,请对 files 资源使用 download() 方法。该方法接受 file_idmime_typerevision_id 的查询参数:

  • 必需。file_id 查询参数是要下载的文件的 ID。

  • 可选。mime_type 查询参数表示该方法应使用的 MIME 类型。只有在下载非 Blob 媒体内容(例如 Google Workspace 文档)时,才会显示此选项。如需查看支持的 MIME 类型的完整列表,请参阅导出 Google Workspace 文档的 MIME 类型

    如果未设置 MIME 类型,系统会使用默认 MIME 类型下载 Google Workspace 文档。如需了解详情,请参阅默认 MIME 类型

  • 可选。revision_id 查询参数是要下载的文件的修订 ID。只有在下载 blob 文件、Google 文档和 Google 表格时,才会显示此选项。下载不受支持的文件的特定修订版时,返回错误代码 INVALID_ARGUMENT

download() 方法是下载 MP4 格式 Vids 文件的唯一方法,通常最适合下载大多数视频文件。

为 Google 文档或表格生成的下载链接最初会返回重定向。点击新的链接即可下载文件。

用于启动 LRO 的 download() 方法请求以及用于提取最终下载 URI 的请求都应使用资源键。如需了解详情,请参阅使用资源键访问通过链接共享的云端硬盘文件

请求协议如下所示。

POST https://www.googleapis.com/drive/v3/files/{FILE_ID}/download

FILE_ID 替换为您要下载的文件的 fileId

默认 MIME 类型

如果在下载非 blob 内容时未设置 MIME 类型,系统会分配以下默认 MIME 类型:

文档类型 格式 MIME 类型 文件扩展名
Google Apps 脚本 JSON application/vnd.google-apps.script+json .json
Google 文档 Microsoft Word application/vnd.openxmlformats-officedocument.wordprocessingml.document .docx
Google 绘图 PNG image/png .png
Google 表单 ZIP application/zip .zip
Google 表格 Microsoft Excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet .xlsx
Google 协作平台 原始文本 text/raw .txt
Google 幻灯片 Microsoft PowerPoint application/vnd.openxmlformats-officedocument.presentationml.presentation .pptx
Google Vids MP4 application/mp4 .mp4
Jamboard PDF application/pdf .pdf

下载响应

调用 download() 方法时,响应正文由表示长时间运行的操作的资源组成。该方法通常会返回用于下载文件内容的链接。

{
  "done": true,
  "metadata": {
    "@type": "type.googleapis.com/google.apps.drive.v3.DownloadFileMetadata",
    "resourceKey": "RESOURCE_KEY"
  },
  "name": "NAME",
  "response": {
    "@type": "type.googleapis.com/google.apps.drive.v3.DownloadFileResponse",
    "downloadUri": "DOWNLOAD_URI",
    "partialDownloadAllowed": false
  }
}

此输出包括以下值:

请注意,partialDownloadAllowed 字段表示是否允许部分下载。下载 blob 文件内容时为 true。

获取长时间运行的操作的详细信息

长时间运行的操作是可能需要大量时间才能完成的方法调用。通常,新创建的下载操作最初会返回待处理状态 (done=null),尤其是 Vids 文件。

您可以使用 Drive API 提供的 operations 资源,通过添加服务器分配的唯一名称来检查正在处理的 LRO 的状态。

get() 方法可异步获取长时间运行的操作的最新状态。客户端可以使用此方法,按 API 服务建议的时间间隔来轮询操作结果。

轮询长时间运行的操作

如需轮询可用的 LRO,请反复调用 get() 方法,直到操作完成。在每个轮询请求之间使用指数退避算法,例如 10 秒。

LRO 最长可保留 12 小时,但在某些情况下可能会保留更长时间。此时长可能会发生变化,并且不同类型的文件的时长可能不同。资源过期后,您需要发出新的 download() 方法请求。

get() 的任何请求都应使用资源键。如需了解详情,请参阅使用资源键访问通过链接共享的云端硬盘文件

请求协议显示在此处。

方法调用

operations.get(name='NAME');

NAME 替换为操作的服务器分配的名称,如对 download() 方法请求的响应中所示。

curl

curl -i -H \
      'Authorization: Bearer $(gcloud auth print-access-token)" \
      'https://googleapis.com/drive/v3/operations/NAME?alt=json'

NAME 替换为操作的服务器分配的名称,如对 download() 方法请求的响应中所示。

该命令使用路径 /drive/v3/operations/NAME

请注意,name 仅在 download() 请求的响应中返回。由于云端硬盘 API 不支持 List() 方法,因此无法通过其他方式检索该值。如果 name 值丢失,您必须再次调用 download() 方法请求来生成新响应。

get() 请求的响应包含一个表示长时间运行的操作的资源。如需了解详情,请参阅下载响应

当响应包含已完成状态 (done=true) 时,表示长时间运行的操作已完成。

下载修订版本

您可以使用 files 资源中的 headRevisionId 字段的值下载最新修订版。这会提取与您之前检索的文件的元数据对应的修订版本。如需下载仍存储在云端的文件的所有先前修订版本的数据,您可以使用 fileId 参数对 revisions 资源调用 list() 方法。这会返回文件中的所有 revisionIds

如需下载 blob 文件的修订内容,您必须对 revisions 资源调用 get() 方法,并提供要下载的文件的 ID、修订的 ID 和 alt=media 网址参数。alt=media 网址参数会告知服务器,请求以其他响应格式下载内容。

您无法使用 get() 方法和 alt=media 网址下载 Google 文档、表格、幻灯片和 Vids 的修订版本。否则,它会生成 fileNotDownloadable 错误。

alt=media 网址参数是适用于所有 Google REST API 的系统参数。如果您使用的是适用于 Drive API 的客户端库,则无需明确设置此参数。

请求协议如下所示。

GET https://www.googleapis.com/drive/v3/files/{FILE_ID}/revisions/{REVISION_ID}?alt=media

替换以下内容:

  • FILE_ID:您要下载的文件的 fileId
  • REVISION_ID:您要下载的修订版本的 revisionId

Google 文档、绘图和幻灯片修订会自动递增修订编号。不过,如果删除了修订版本,数字序列可能会出现空缺,因此您不应依赖于顺序数字来检索修订版本。

排查 LRO 问题

LRO 失败时,其响应会包含规范的 Google Cloud 错误代码

下表说明了每个代码的原因,并提供了相应的处理建议。对于许多错误,建议采取的措施是使用指数退避算法再次尝试请求。

如需详细了解该错误模型及其使用方法,请参阅 API 设计指南

代码 枚举 说明 建议采取的措施
1 CANCELLED 操作已取消(通常是被调用者取消)。 重新运行该操作。
2 UNKNOWN 当从另一个地址空间接收到的 Status 值属于此地址空间中未知的错误空间时,可能返回此错误。如果 API 错误未返回足够的信息,则错误可能会转换为此错误。 使用指数退避算法重试。
3 INVALID_ARGUMENT 客户端指定的参数无效。此错误与 FAILED_PRECONDITION 不同。无论系统状态如何,INVALID_ARGUMENT 都会指出有问题的参数,例如文件名格式错误。 在解决问题之前,请勿重试。
4 DEADLINE_EXCEEDED 期限已到,但操作尚未完成。对于更改系统状态的操作,即使操作已成功完成,也可能会返回此错误。例如,服务器的成功响应可能会延迟足够长的时间以使截止期限过期。 使用指数退避算法重试。
5 NOT_FOUND 找不到某个请求的实体,例如 FHIR 资源。 在解决问题之前,请勿重试。
6 ALREADY_EXISTS 客户端尝试创建的实体(例如 DICOM 实例)已存在。 在解决问题之前,请勿重试。
7 PERMISSION_DENIED 调用方无权执行指定的操作。此错误代码并不意味着请求有效,或者请求的实体存在或满足其他先决条件。 在解决问题之前,请勿重试。
8 RESOURCE_EXHAUSTED 某些资源已用尽,例如每个项目的配额。 使用指数退避算法重试。配额可能会随着时间的推移而变得可用。
9 FAILED_PRECONDITION 操作被拒绝,因为系统未处于执行该操作所需的状态。例如,要删除的目录非空,或者 rmdir 操作应用于非目录。 在解决问题之前,请勿重试。
10 ABORTED 操作已中止,通常是由于序列程序检查失败或事务中止等并发问题。 使用指数退避算法重试。
11 OUT_OF_RANGE 尝试执行的操作已超出有效范围,例如查找或读取操作已超出文件末尾。与 INVALID_ARGUMENT 不同,此错误指示的问题可以通过改变系统状态得到修复。 在解决问题之前,请勿重试。
12 UNIMPLEMENTED 操作未在云端硬盘 API 中实现或不受支持/未启用。 不重试。
13 INTERNAL 内部错误。这表示在底层系统中处理时遇到意外错误。 使用指数退避算法重试。
14 UNAVAILABLE 无法使用 Drive API。这很可能是一种暂时情况,可以通过使用指数退避算法重试来纠正。请注意,重试执行非幂等操作并非总是安全的。 使用指数退避算法重试。
15 DATA_LOSS 数据丢失或损坏且不可恢复。 请与您的系统管理员联系。如果发生数据丢失或损坏,系统管理员可能需要与支持代表联系。
16 UNAUTHENTICATED 请求没有相应操作的有效身份验证凭据。 在解决问题之前,请勿重试。