Los SDK de Arbol envían cada llamada una vez y nunca la reintentan, así que tu código decide. Lo deciden dos preguntas: si una repetición puede tener éxito (lo responde el retryable del error) y si una repetición es segura (lo responde el efecto de la operación).
El efecto de cada operación
La página de cada operación en la referencia de la API indica su efecto (Effect):
| Efecto | Qué hace la operación | Repetirla |
|---|---|---|
| Lee | No cambia nada. | Es seguro. |
| Escribe | Crea o cambia algo. | Es seguro solo si la operación es idempotente, o una vez que confirmaste que el primer intento no se aplicó. |
| Elimina | Elimina o cancela algo. | Igual que una escritura. |
El método HTTP no te dice el efecto. agenda.bookings.lookup es un POST que lee, y agenda.bookings.cancel es un POST que elimina: lee en cambio el efecto de la operación.
Cuándo puede servir repetir
error.retryable dice si repetir la misma solicitud puede tener éxito. Estos códigos comunes son reintentables:
| Estado | code |
Qué hacer |
|---|---|---|
429 |
RATE_LIMITED |
Demasiadas solicitudes de esta credencial. Espera los segundos de Retry-After y luego repite. |
503 |
UPSTREAM_UNAVAILABLE |
Aplica backoff y luego repite. |
504 |
UPSTREAM_TIMEOUT |
Aplica backoff y luego repite una lectura. Una escritura puede haberse aplicado: consulta más abajo. |
Los servicios agregan sus propios códigos reintentables, como PROVIDER_UNAVAILABLE en gMedic, SURA y Visoft. Cuando retryable es false, la misma solicitud volverá a fallar: primero cambia la entrada, la credencial o el estado.
Escrituras con resultado desconocido
Algunos fallos no dicen si una escritura ocurrió:
502 OUTCOME_UNKNOWN: puede que la operación se haya aplicado. Revisa su resultado antes de repetirla.- Un timeout, o ninguna respuesta. Una escritura que terminó con
504 UPSTREAM_TIMEOUT, o cuya conexión se cayó, también puede haberse aplicado.
Concilia antes de repetir: lee el registro o lista lo que el primer intento habría creado. Varias operaciones lo dicen en su descripción, como gmedic.patients.create (“reconcile an unknown outcome before repeating”), visoft.appointments.create (“Never repeat a booking whose outcome is unknown”) y raiz.channels.create, que no es idempotente: lista los canales antes de intentarlo de nuevo.
El SDK de Rust etiqueta cada fallo con un outcome: Refused (no pasó nada), NotSent (la solicitud nunca salió) o Unknown (una escritura que puede haber ocurrido).
Operaciones que es seguro repetir
Algunas escrituras están diseñadas para repetirse:
- Operaciones idempotentes. El efecto de una operación dice idempotent cuando repetirla con la misma entrada no tiene ningún efecto adicional, y not idempotent cuando una repetición puede volver a actuar. Entre las escrituras,
raiz.agents.updateyagenda.waitlist.joinson idempotentes, mientras queraiz.contacts.createysura.appointments.createno lo son. Los clientes MCP ven lo mismo en elidempotentHintde la herramienta. - Claves de idempotencia.
agenda.appointments.createrecibe unidempotencyKey, único dentro de la organización: reutilizarlo devuelve la cita original.sura.appointments.createtambién recibe uno, que se reutiliza solo para la misma oferta aceptada. - Repeticiones que no cambian nada. Llamar otra vez a
agenda.waitlist.joinpara el mismo paciente, servicio y motivo devuelve la misma entrada abierta. Cancelar otra vez una tarea de Raíz conraiz.tasks.cancelno cambia nada. - Validación de versión. Las actualizaciones que reciben
expectedVersionse aplican solo si el registro no ha cambiado desde que leíste esa versión. En Raíz, repetir una actualización que ya se aplicó falla conVERSION_CONFLICTen lugar de aplicarse dos veces.
Respuestas pendientes en SURA
Una llamada a SURA puede responder "status": "pending" con un operationId y retryAfterSeconds en lugar de su resultado, mientras SURA termina una solicitud anterior. La operación sigue en curso. Después de retryAfterSeconds, obtén el resultado con sura.operations.get, o repite la llamada idéntica, que devuelve la misma operación en lugar de iniciar otra.
Una política de reintentos
- Respeta
retryable: false. Corrige la solicitud antes de enviarla de nuevo. La excepción esOUTCOME_UNKNOWN: revisa si la escritura se aplicó y repítela solo si no se aplicó. - Repite las lecturas cuando
retryableseatrue, o cuando no haya llegado ninguna respuesta. - Repite escrituras y eliminaciones solo cuando la operación sea idempotente, o una vez que confirmaste que el primer intento no se aplicó.
- Espera entre intentos. Usa
Retry-Aftercuando la respuesta lo traiga. Si no, aplica backoff exponencial con jitter y limita el número de intentos. - Registra el
X-Request-Idde cada intento, para poder rastrear un fallo.