---
name: retry_sync
kind: function
lang: py
domain: core
version: "1.0.0"
purity: impure
signature: "def retry_sync(func: Callable[[], T], max_retries: int, base_delay: float = 0.5, max_delay: float = 8.0, jitter: bool = True, is_retryable: Callable[[Exception], bool] | None = None) -> T"
description: "Reintenta una funcion sincrona en errores transitorios con exponential backoff. Por defecto usa classify_api_error para decidir si reintentar. Hace time.sleep entre intentos."
tags: [retry, backoff, exponential, sync, resilience, api]
uses_functions: [classify_api_error_py_core, compute_backoff_delay_py_core]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [time, typing]
params:
  - name: func
    desc: "Función a reintentar"
  - name: max_retries
    desc: "Número máximo de reintentos"
  - name: base_delay
    desc: "Delay inicial en segundos entre reintentos"
  - name: max_delay
    desc: "Delay máximo en segundos"
  - name: jitter
    desc: "Si True, añade variabilidad al delay"
  - name: is_retryable
    desc: "Predicado opcional para decidir si reintentar"
output: "Resultado de ejecutar la función si tiene éxito"
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/core/retry_sync.py"
---

## Ejemplo

```python
import httpx

# Reintentar una llamada HTTP transitoria hasta 3 veces
response = retry_sync(
    func=lambda: httpx.get("https://api.example.com/data"),
    max_retries=3,
)

# Con predicado personalizado
retry_sync(
    func=my_db_query,
    max_retries=5,
    is_retryable=lambda e: "deadlock" in str(e),
)
```

## Notas

Impure: hace `time.sleep` entre reintentos. Usa `classify_api_error` como clasificador por defecto — solo reintenta errores marcados como "transient". Si `is_retryable` devuelve False en la primera excepcion, re-raise inmediato sin esperar. El parametro `max_retries` es el numero de reintentos despues del primer intento (total de llamadas = max_retries + 1).
