Повторіть виклик, не роблячи роботу двічі
PHPДайте запуску чи руху кредитів ключ, який називає його одиницю роботи, — тоді на повтор, від SDK, від вашої черги чи від вашого коду, відповідять, а не зроблять роботу знову.
5 хв читання
Запуск флоу й рух кредитів несуть ключ ідемпотентності. Ключ називає одну одиницю роботи. Коли той самий виклик приходить ще раз під тим самим ключем, Slen відповідає на нього, а не робить роботу знову, — тому виклик, повторений після тайм-ауту, падіння чи повтору вашої черги, — це не друге виконання, не друга витрата й не друге поповнення.
Ключ, який створює SDK, і ключ, який передаєте ви
Ключ приймають п’ять викликів: operations.execute(), operations.executeAsync(), customers.topUp(), customers.charge() і customers.adjust(). Ключ — це idempotencyKey опцій виклику: ExecuteOptions запуску, MovementOptions руху кредитів — ті самі імена в обох SDK. Коли ви не передаєте ключ, SDK створює для цього виклику новий випадковий.
Ключ, створений SDK, покриває лише власні повтори SDK. SDK надсилає запит ще раз під тим самим ключем, коли відповіді не було, після
429або503— Повтори й тайм-аути.Виклик, який ваш код робить ще раз, — повтор вашої черги, друге натискання кнопки — отримує новий випадковий ключ, а новий ключ — це нова робота: флоу виконується знову, кредити рухаються знову.
Порожній ключ, який ви передали, відхиляється до надсилання запиту, з кодом
invalid_request. SDK ніколи не підставляє на його місце свій.
Передавайте власний ключ кожному запуску й кожному руху кредитів. Без нього виклик, який повторює ваш код, виконується двічі.
Вибрати ключ
Робіть ключ з одиниці роботи, щоб кожен повтор роботи ніс той самий ключ, а наступна одиниця роботи отримувала новий: замовлення та його крок (order-42:email), рахунок-фактура та його поповнення (invoice-7781:topup) або задача вашої черги, яка надсилає виклик.
use Slen\Sdk\IdempotencyKeys;
// The id of the job of your own queue that sends this request.
$jobId = 'a1f7c2e9';
$key = IdempotencyKeys::forJob($jobId, 'generate_email');IdempotencyKeys::forJob() робить job:<id>:<operation> — один ключ на всі спроби задачі. Задача, яка виконується знову, отримує назад перше виконання. IdempotencyKeys::generate() робить випадковий ключ — той, який SDK створює, коли ви не передали свій.
Ключ — не довший за 190 символів. Довший відхиляється з
422, перш ніж щось виконається.Ключ належить проєкту API-ключа. Усередині проєкту давайте кожній одиниці роботи свій ключ.
Чим відповідають на повтор
use Slen\Sdk\Modules\Operations\Options\ExecuteOptions;
$input = ['messages' => [['role' => 'user', 'content' => 'Write a short follow-up email.']]];
$execution = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: $key));
echo $execution->status->value, PHP_EOL;// The queue runs the same job again, so the key is the same.
$again = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: $key));
if ($again->replayed) {
echo "Execution {$again->executionId} ran once. This answer is a replay.", PHP_EOL;
}| Виклик | Повтор під його ключем |
|---|---|
| Запуск | Виконання, яке почав перший запит, у тому стані, у якому воно є в цю мить, із replayed, що дорівнює true. Флоу не виконується знову |
| Поповнення, списання чи коригування | Перша відповідь, протягом 24 годин. Після цього — рахунок таким, яким він став. Кредити рухаються один раз. Відхилений рух не зберігається, і його повтор — нова спроба |
На виконання, яке не закінчилося, відповідають
202і статусомqueued,waitingабоrunning—running, коли виконання першого запиту ще триває.На виконання, яке закінчилося, відповідають
200і його результатом. Так і тоді, коли перший запит закінчився помилкою: повтор читає статус виконання та йогоerror_code.На повторі може прийти
cost.actual, коли в першій відповіді його не було: розрахунок за виклики моделей іде після кінця виконання.
Інші виклики SDK ключа не приймають. Читання нічого не змінює, а створення клієнта, налаштування рахунку, блокування й розблокування лишають той самий стан, скільки б разів їх не надіслали. Видалення, яке SDK повторив, коли відповіді не було, вважається зробленим, коли клієнта вже немає, — Повтори й тайм-аути. Ті самі відповіді в термінах API наводить стаття Ідемпотентність.
Той самий ключ з іншим запитом
use Slen\Sdk\Exceptions\IdempotencyConflictException;
try {
$slen->operations()->execute(
'generate_email',
['messages' => [['role' => 'user', 'content' => 'Write a short thank-you email.']]],
new ExecuteOptions(idempotencyKey: $key),
);
} catch (IdempotencyConflictException $exception) {
echo "Refused: {$exception->errorCode}", PHP_EOL;
}Ключ, який уже називає одну одиницю роботи, не приймає іншу: API відповідає 409 із кодом idempotency_conflict, нічого не виконується й нічого не рухається, а SDK кидає помилку.
Виняток — IdempotencyConflictException. idempotency_in_progress приходить тим самим винятком: перший запит під цим ключем ще не закінчився. Надішліть виклик ще раз пізніше, під тим самим ключем.
Для запуску інший вхід, інший контекст, інший клієнт чи інший режим — це інший запит.
Для руху кредитів інший клієнт, тип кредитів, вид чи сума — це інший запит, а в перші 24 години — й інша примітка.
Виконання, яке впало, зберігає свій ключ. Щоб виконати роботу знову, після того як ви виправили запит, надішліть його під новим ключем.
Що читати далі
Ідемпотентність — заголовок, які запити API його вимагають і чим кожен відповідає на повтор.
Асинхронні запуски й очікування — прочитайте результат виконання, яке повтор застав незакінченим.
Клієнти та кредити — рухи кредитів та їхні ключі.