رفتن به محتوا

تکرارپذیری و تلاش دوباره

ممکن است درخواستی درست انجام شود اما پاسخش در شبکه گم شود. فرستادن دوبارهٔ آن نباید جلسهٔ دومی بسازد یا هزینهٔ پرسش دوم را بگیرد. هدر Idempotency-Key تلاش دوم را بی‌خطر می‌کند.

کدام مسیرها کلید می‌گیرند

Section titled “کدام مسیرها کلید می‌گیرند”

سه مسیری که دقیقه خرج می‌کنند هدر Idempotency-Key را می‌پذیرند:

مسیر دسترسی پاسخ تکرار درخواست
POST /recordings recordings:write 202 با همان جلسه
POST /recordings/{id}/ask recordings:query 200 با همان پاسخ
POST /series/{id}/ask series:query 200 با همان پاسخ
  • کلید ۸ تا ۶۴ نویسه است، پس از این‌که فاصله‌های دو سرش حذف شود. هر مقدار دیگری پاسخ 400 VALIDATION می‌گیرد.
  • فرستادن کلید اختیاری است، اما بهتر است در هر درخواست به این مسیرها بفرستید: بدون آن، لُب نمی‌تواند تلاش دوباره را از درخواست تازه تشخیص دهد.
  • در دو مسیر پرسش، کلید را می‌توانید در بدنه هم با نام idempotencyKey بفرستید. اگر هر دو را بفرستید، هدر حساب می‌شود.
  • مسیرهای دیگر دقیقه‌ای خرج نمی‌کنند و کلیدی هم نمی‌گیرند.
Terminal window
key=$(uuidgen) # one key for this meeting, kept for every retry of it
curl https://app.lobbe.ai/api/v1/recordings \
-H "Authorization: Bearer $LOBBE_TOKEN" \
-H "Idempotency-Key: $key" \
-F "audio=@meeting.m4a;type=audio/mp4"

اگر درخواستی را با همان کلید دوباره بفرستید، لُب آن را دوباره اجرا نمی‌کند و همان چیزی را برمی‌گرداند که درخواست اول ساخته است.

  • جلسه: 202 با همان جلسه، با id آن و وضعیت کنونی‌اش. نه جلسهٔ دومی ساخته می‌شود و نه هزینهٔ دومی گرفته می‌شود، و سقف روزانهٔ توکن هم آن را یک بار می‌شمارد.
  • پرسش: 200 با پاسخ اول، و هزینه‌ای گرفته نمی‌شود.
  • تکرار درخواست حتی وقتی به سقفی رسیده‌اید پاسخ می‌گیرد: سقف‌های روزانهٔ خود لُب یا سقف روزانهٔ توکن.
  • لُب فقط کلید را مقایسه می‌کند. همان کلید با فایلی دیگر یا پرسشی دیگر باز هم همان جلسه یا همان پاسخ اول را برمی‌گرداند و درخواست تازه هرگز فرستاده نمی‌شود. هر درخواست تازه کلید تازه‌ای لازم دارد.
  • فقط درخواستی تکرار می‌شود که انجام شده باشد. درخواستی که با خطا پاسخ گرفته چیزی ذخیره نکرده است، پس فرستادن دوباره‌اش با همان کلید آن را واقعاً اجرا می‌کند. این همان چیزی است که پس از خطای 5xx، یا پس از 402 وقتی صاحب حساب دقیقه خرید، می‌خواهید.
  • 503 UPLOAD_IN_PROGRESS یعنی درخواست اولی که این کلید را داشته هنوز در حال ذخیرهٔ صدای خود است. به اندازهٔ ثانیه‌هایی که Retry-After می‌گوید صبر کنید و همان درخواست را دوباره بفرستید تا همان جلسه را برگرداند.

کلید از آنِ صاحب حساب است و منقضی نمی‌شود

Section titled “کلید از آنِ صاحب حساب است و منقضی نمی‌شود”
  • کلید منقضی نمی‌شود، نه پس از ۲۴ ساعت و نه پس از یک هفته. کلید یک جلسه در تمام عمر جلسه‌ای که ساخته با آن می‌ماند، حتی پس از حذف آن جلسه. کلید یک پرسش هم با پرسش‌های همان جلسه یا سری می‌ماند.
  • کلید جلسه مال کل حساب است. هر کلید فقط یک جلسه می‌سازد، در خود برنامه و در همهٔ توکن‌های حساب. کلید پرسش مال یک جلسه یا یک سری است، پس در جلسهٔ دیگری می‌توان همان کلید را به کار برد.
  • هر توکن فقط درخواست‌های خودش را تکرار می‌کند. کلیدی که توکن دیگری از این حساب، یا خود برنامه، پیش‌تر به کار برده پاسخ 409 IDEMPOTENCY_KEY_IN_USE می‌گیرد. این پاسخ نه شناسهٔ جلسه‌ای دارد و نه پاسخ پرسشی، و جلسه یا پاسخ قبلی هرگز به این توکن نمی‌رسد.

پس برای هر درخواست تازه یک UUID تصادفی بفرستید. هرگز کلید را از روی فایل نسازید، مثلاً از هش صدا: دو دستیارِ یک حساب که هر دو از یک فایل هش بگیرند کلید یکسانی می‌فرستند، و دومی به‌جای جلسه‌اش پاسخ 409 IDEMPOTENCY_KEY_IN_USE می‌گیرد.

  • کلید را یک بار بسازید، پیش از تلاش اول، و برای همهٔ تلاش‌های دوبارهٔ همان درخواست نگهش دارید. اگر ابزار شما ممکن است از نو اجرا شود، کلید را کنار همان کار ذخیره کنید.
  • خطای شبکه و 5xx: همان درخواست را با همان کلید دوباره بفرستید و هر بار بیشتر صبر کنید (۲ ثانیه، بعد ۴، ۸ و همین‌طور، تا حدی که خودتان تعیین می‌کنید). اگر تلاش اول در واقع انجام شده بود، تلاش دوباره نتیجهٔ همان را می‌گیرد.
  • 429: به اندازهٔ ثانیه‌هایی که Retry-After می‌گوید صبر کنید و همان درخواست را با همان کلید بفرستید. برای سقف‌های روزانه این زمان ممکن است چند ساعت باشد. پاسخ 429 بدون Retry-After با صبر کردن برطرف نمی‌شود: یا TOKEN_DAILY_CAP است و همین درخواست به‌تنهایی از سقف بزرگ‌تر است، یا DAILY_LIMIT_REACHED خود لُب برای فرستادن جلسه. دست نگه دارید و به صاحب حساب بگویید.
  • پرسشی که شکست بخورد (502 GENERATE_FAILED) هزینه‌ای ندارد، اما ممکن است جزو سقف روزانهٔ پرسش‌های لُب شمرده شود: پیش از تلاش دوباره صبر کنید و آن را پشت سر هم تکرار نکنید.
  • دیگر خطاهای 4xx: درخواست به همین شکل کار نمی‌کند. آن را همان‌طور که کدش می‌گوید اصلاح کنید؛ خطاها را ببینید. 409 IDEMPOTENCY_KEY_IN_USE کلید تازه‌ای لازم دارد.

فرستادن جلسه با همهٔ این قاعده‌ها (به uuidgen نیاز دارد، اما هر UUID تصادفی دیگری هم کار می‌کند):

Terminal window
key=$(uuidgen)
delay=2
for attempt in 1 2 3 4 5 6; do
rm -f headers.txt body.json
code=$(curl -sS -o body.json -D headers.txt -w '%{http_code}' \
https://app.lobbe.ai/api/v1/recordings \
-H "Authorization: Bearer $LOBBE_TOKEN" \
-H "Idempotency-Key: $key" \
-F "audio=@meeting.m4a;type=audio/mp4") || code=000
wait=$(awk -F': *' 'tolower($1) == "retry-after" { print $2 + 0 }' headers.txt 2>/dev/null)
case "$code" in
202) cat body.json; break ;;
429) [ -n "$wait" ] || { cat body.json; break; }; sleep "$wait" ;;
5?? | 000) sleep "${wait:-$delay}"; delay=$((delay * 2)) ;;
*) cat body.json; break ;;
esac
[ "$attempt" = 6 ] && { echo "gave up after 6 tries"; cat body.json 2>/dev/null; }
done

000 یعنی خطای شبکه: curl هیچ پاسخی نگرفته است. این حلقه هر بار همان کلید را می‌فرستد، پس هر چند بار هم که لازم شود، فقط یک جلسه ساخته می‌شود.