Bỏ qua tới phần tài liệu
SDK

Thử lại và idempotency

Cái gì được thử lại, cái gì cố tình không, và vì sao một lần gửi được thử lại không thể bị trùng.

Các lần gửi

Client gắn một Idempotency-Key vào mọi lần gửi (emails.send, emails.sendBatchtemplates.send), sinh ra một lần cho mỗi **lời gọi** và được chính các lần thử lại của lời gọi đó dùng lại. API chiếm giữ khoá ấy trước khi điều phối bất cứ thứ gì, nên một lần thử lại sẽ phát lại thông điệp gốc thay vì gửi cái thứ hai, trong khi hai lời gọi send() có chủ ý vẫn gửi hai lần. Đó là hai ý định khác nhau và chúng vẫn được giữ khác nhau.

Hãy truyền idempotencyKey của riêng bạn để kéo dài bảo đảm đó xuyên qua các tiến trình, nhờ vậy một job bị sập rồi chạy lại sẽ phát lại các lần gửi thay vì lặp lại chúng.

idempotency.ts
await openemail.emails.send(message, { idempotencyKey: `invoice:${invoice.id}` })

Hãy dẫn xuất nó từ chính thứ khiến lần gửi trở nên cần thiết. Đừng bao giờ dẫn xuất từ đồng hồ. Dùng lại một khoá với body khác sẽ bị từ chối với idempotency_key_reuse chứ không âm thầm phát lại.

Mọi thứ còn lại

Mọi thao tác đọc đều được thử lại. Một thao tác ghi chỉ được thử lại ở nơi một yêu cầu thứ hai giống hệt không thể mang nghĩa nào khác với yêu cầu đầu, và một lần gửi đủ điều kiện vì khoá idempotency biến một lần lặp thành một lần phát lại.

Lời gọiCó thử lạiVì sao
Mọi thao tác đọcKhông có gì thay đổi.
`emails.send`, `emails.sendBatch`, `templates.send`Một khoá idempotency biến một lần lặp thành một lần phát lại.
`emails.cancel`, `emails.reschedule`Một phép gán thuần tuý về một trạng thái có tên.
`threads.update`, `threads.trash`Một phép gán nhãn. Áp dụng hai lần cũng chính là áp dụng một lần.
`threads.snooze`, `threads.unsnooze`Thời điểm đánh thức nằm trong body, không phải suy ra từ thời điểm yêu cầu tới.
`labels.update`, `webhooks.update`, `settings.update`, `roles.update`, `members.update`Một phép gán thuần tuý các trường có tên.
`members.grantAddress`, `rules.reorder`Việc cấp quyền là một upsert, và thứ tự được nêu đầy đủ.
`templates.publish`Xuất bản một head vốn đã được xuất bản sẽ trả nó về nguyên vẹn.
`templates.preview`, `rules.test`Chúng chỉ kết xuất hoặc đánh giá, và không ghi gì cả.
`drafts.create`, `labels.create`, `webhooks.create`, `templates.create`, `rules.create`, `roles.create`, `tempMail.create`KhôngMột lần thử lại sẽ để lại hai đối tượng.
`drafts.update`KhôngHãy đọc id từ kết quả của mỗi thao tác ghi thay vì dùng lại id bạn đã gửi.
`drafts.delete`, `labels.delete`, `webhooks.delete`, `templates.delete`, `rules.delete`, `roles.delete`, `members.remove`, `members.revokeAddress`, `tempMail.delete`, `tempMail.deleteMessage`KhôngMột lần thử lại sau khi mất phản hồi sẽ báo thất bại cho công việc vốn đã thành công.
`webhooks.rotateSecret`KhôngMột lần xoay khoá thứ hai sẽ làm vô hiệu bí mật mà lần đầu đã trả về.
`webhooks.test`KhôngNó sẽ gửi một lần chuyển giao giả lập thứ hai.
`emails.translate`KhôngNó tiêu tốn các lời gọi mô hình, nên một lần thử lại sau một yêu cầu không được trả lời chỉ mua cùng một câu trả lời hai lần.
Mọi thao tác ghi khácKhôngGửi một lần, và một thất bại được báo cáo chứ không được lặp lại.

Cơ chế giãn thời gian chờ

  • Bị giới hạn bởi maxRetries trên client, mặc định là hai lần thử thêm.
  • Chỉ sau một sự cố mạng hoặc một 408, 500, 502, 503 hay 504. Một 429 chỉ được thử lại khi nó mang theo Retry-After, mà API này không gửi header đó, nên một giới hạn tốc độ sẽ ném lỗi ngay. Mọi status khác đều ném lỗi lập tức.
  • Tăng theo cấp số nhân từ nửa giây lên tới tám giây, kèm jitter, để cả một đội máy không đồng bộ lại với nhau đúng lúc hệ thống hồi phục.
  • Được điều nhịp bởi Retry-After ở cả hai dạng, số giây trễ và HTTP-date. Khi máy chủ nêu ra một thời gian chờ, client chờ đúng chừng ấy thay vì tự giãn thời gian.
  • Một máy chủ yêu cầu chờ lâu hơn một phút được hiểu là đang bảo client dừng lại chứ không phải ngủ, nên lỗi được ném ra kèm retryAfterSeconds. Quay lại sớm hơn mức nó yêu cầu thì không phải là tôn trọng nó.
  • AbortSignal của người gọi không bao giờ được thử lại. Huỷ sẽ ném ra một OpenEmailNetworkError ngay lập tức, dù đang trong lúc gửi yêu cầu hay đang chờ trước lần thử kế tiếp.