Saltar al contenido principal

Generación por ciclos para catálogos grandes

El modo ciclo divide tu catálogo de productos en lotes de tamaño fijo para que la generación del feed se complete de forma fiable incluso en hosting compartido con límites de tiempo de PHP ajustados.

nota

Disponible desde v2.0.0

Descripción general

Sin el modo ciclo, generar un feed requiere procesar todos los productos en una única solicitud PHP ininterrumpida. En tiendas con miles de productos —o en hosting compartido donde el servidor corta las solicitudes después de 30–60 segundos— esto produce un feed incompleto o vacío.

El modo ciclo resuelve esto procesando un número configurable de productos por solicitud, guardando el progreso tras cada lote y encadenando solicitudes automáticamente hasta que se escribe el catálogo completo. El archivo de feed que lee Facebook es siempre una instantánea completa y válida de la última generación exitosa; nunca se reemplaza por un archivo parcial.

Hay dos áreas del módulo que controlan el comportamiento del ciclo:

  • Pestaña Opciones de producto — el campo Elementos del ciclo (FPF_CYCLE) activa o desactiva el modo ciclo.
  • Pestaña Opciones de generación — controles de rendimiento y seguridad que determinan cómo funciona el motor de ciclos.

Cómo funciona el modo ciclo

Cuando el modo ciclo está activado, cada solicitud de generación sigue estos pasos:

  1. Primera solicitud — se inicia una generación nueva. El motor consulta los primeros N productos (donde N es el tamaño de tu ciclo), los escribe en un archivo de feed temporal y guarda su posición en feeds/progress.json.

  2. Continuación — una vez escrito el primer lote, el motor realiza una llamada cURL interna a sí mismo, pasando la posición actual y el estado como datos POST. La nueva solicitud retoma exactamente donde dejó la anterior, incrementa el contador de ciclos y procesa el siguiente lote.

  3. Finalización — cuando se procesa el último producto, el archivo temporal se mueve a la ubicación definitiva del feed. Solo en ese momento la URL del feed en directo refleja la nueva generación. Facebook siempre lee un archivo completo.

  4. Archivo de progresofeeds/progress.json se actualiza cada 5 productos durante un ciclo y en cada límite de ciclo. El panel de administración lee este archivo para mostrar la barra de progreso en tiempo real y los recuentos de productos. El archivo contiene meta.total_feeds, meta.completed_feeds y meta.global_percent para que la interfaz pueda mostrar un porcentaje preciso sin cargar el feed completo.

  5. Recuperación ante fallos — si una solicitud es interrumpida (tiempo de espera del servidor, error de memoria, cierre del navegador), la siguiente llamada cron programada comprueba si progress.json tiene menos de 120 segundos de antigüedad. Si es así, la generación ya está en curso y la nueva llamada finaliza correctamente. Si han transcurrido más de 120 segundos desde la última actualización de progreso, el motor asume que la ejecución anterior se bloqueó y comienza una nueva generación desde cero.

El guardián de 120 segundos está definido en el código. En servidores muy lentos o con ciclos muy grandes, puedes evitar reinicios falsos manteniendo el tamaño del ciclo lo suficientemente pequeño para que cada lote se complete en menos de 120 segundos.

Pestaña de opciones de producto mostrando el campo Elementos del ciclo

Pestaña de opciones de generación mostrando los campos de tamaño de fragmento, ciclo de guardado y límite de ciclos

Configuración

Activar el modo ciclo

Ve a Módulos > Gestor de módulos > Facebook & Instagram Product Catalogue Feed Pro > Configurar y abre la pestaña Opciones de producto.

CampoUbicaciónValoresPredeterminadoDescripción
Elementos del ciclo (FPF_CYCLE)Opciones de productoCualquier entero positivo, o 0 para desactivar0 (desactivado)Número de productos a procesar por ciclo. Establece 0 para generar todo el catálogo en una sola solicitud. Recomendado: 500–2000 según la complejidad del catálogo.

Cuando Elementos del ciclo es 0, el motor intenta generar todos los productos en una única solicitud. Esto funciona bien en VPS o hosting dedicado sin límites de tiempo, pero es probable que agote el tiempo de espera en hosting compartido con catálogos de más de ~1.000 productos.

Configuración de rendimiento y seguridad

Abre la pestaña Opciones de generación para los siguientes campos.

CampoValoresPredeterminadoMínimoDescripción
Fragmentos de procesamiento de productos (FPF_CHUNK_SIZE)Entero positivo2000Los productos se cargan desde la base de datos en este tamaño de fragmento. Controla el tamaño de la consulta SQL, no el número de productos por ciclo. Reduce este valor si encuentras errores de memoria durante el paso de carga de stock.
Ciclo de guardado de productos (FPF_FEED_UPDATE)Entero ≥ 555Con qué frecuencia (en productos procesados) se vuelca el archivo de feed temporal al disco. Valores más bajos reducen la pérdida de datos en caso de fallo, pero añaden más E/S. Los valores inferiores a 5 se elevan automáticamente a 5.
Ciclo de guardado de overrides de productos (FPF_FEED_UPDATE_OVERRIDES)Entero ≥ 101010Igual que el anterior, pero para los feeds de overrides de idioma y país. Los valores inferiores a 10 se elevan automáticamente a 10.
Número máximo de ciclos (FPF_FEED_UPDATE_CYCLES)Entero ≥ 505050Límite máximo de ciclos que puede usar una generación completa antes de que el motor se detenga. Es una protección contra bucles infinitos. Los valores inferiores a 50 se elevan automáticamente a 50.
Ignorar interrupción (FPF_IGNORE_ABORT)Activado / DesactivadoDesactivadoCuando está activado, llama a ignore_user_abort(true) para que el proceso PHP siga ejecutándose aunque se pierda la conexión con el navegador. Útil para la generación manual desde el visor de consola.

Los valores mínimos para FPF_FEED_UPDATE_OVERRIDES (10) y FPF_FEED_UPDATE_CYCLES (50) se aplican automáticamente al guardar. Si introduces un número inferior, se reemplaza sin mostrar ningún mensaje de advertencia.

Límite de ciclos alcanzado: Si tu catálogo requiere más ciclos que el valor de Número máximo de ciclos, la generación se detiene antes de completarse y el feed puede quedar incompleto. Multiplica el número de productos por 1,2 (para tener en cuenta los feeds de idioma y país) y divídelo por el tamaño del ciclo para estimar el número de ciclos necesarios. Establece el máximo al menos un 20% por encima de esa estimación.

Combinación con cron

El modo ciclo y cron están diseñados para funcionar juntos. La configuración recomendada es:

  1. Establece Elementos del ciclo en un valor que encaje cómodamente dentro del límite de tiempo de ejecución de PHP de tu servidor — normalmente 500 productos tardan entre 10 y 30 segundos según la velocidad del servidor, la complejidad del catálogo y si el envío está activado.
  2. Añade una tarea cron que llame a la URL de generación del feed cada 15–30 minutos. La URL de cron se muestra en la pestaña Generación automática (Tareas Cron).
  3. La primera llamada cron inicia la generación. Si el catálogo necesita varios ciclos, el motor los encadena automáticamente dentro de la misma invocación cron mediante llamadas cURL internas. No es necesario que cron se ejecute una vez por ciclo.

Si la generación del feed para tu catálogo completo tarda más que el intervalo de cron, dos mecanismos te protegen: el guardián de progreso de 120 segundos evita que una segunda llamada cron reinicie una generación en curso, y la URL del feed en directo solo se actualiza cuando una generación se completa, por lo que Facebook siempre lee la última versión completa.

Para catálogos muy grandes (más de 50.000 productos) o servidores donde cURL está restringido, considera ejecutar la generación desde la línea de comandos:

php index.php --fpf_secret_key=YOUR_KEY

La generación por CLI desactiva el enfoque de ciclo por solicitud y ejecuta la generación completa en un único proceso sin la sobrecarga del encadenamiento cURL.

Comportamiento ante el límite de tiempo

Al inicio de cada ciclo, el módulo intenta aumentar el max_execution_time de PHP. El tiempo límite objetivo se calcula a partir del tamaño del ciclo: ciclo_size / 5 segundos cuando las combinaciones están activadas, ciclo_size / 10 segundos en caso contrario. Por ejemplo, con 2.000 productos y combinaciones activadas, se solicitan 400 segundos por ciclo.

Si set_time_limit está desactivado en tu servidor (común en hosting compartido), este ajuste se omite silenciosamente y se aplica el límite existente. Mantén el tamaño del ciclo lo suficientemente pequeño para que cada lote se complete dentro de ese límite.

El módulo también intenta aumentar el límite de memoria de PHP a 1 GB al inicio de la generación si actualmente hay menos de 1 GB asignado y hay suficiente memoria libre del sistema disponible.

Ejemplos de uso

Ejemplo: Hosting compartido con límite de tiempo de 120 segundos

Una tienda con 8.000 productos en hosting compartido. Cada producto tarda unos 15 ms en procesarse (sin combinaciones, sin envío). Eso da aproximadamente 2.000 productos por 30 segundos.

Configuración recomendada:

  • Elementos del ciclo: 1.500 (deja un margen de seguridad por debajo del límite de 120 s)
  • Número máximo de ciclos: 100 (8.000 / 1.500 = ~6 ciclos para el feed principal, más los feeds de idioma y país)
  • Intervalo de cron: cada 15 minutos

Cada llamada cron encadena ~6 ciclos automáticos y completa la generación completa en una sola ejecución.

Ejemplo: Tienda de ropa con combinaciones

Una tienda con 3.000 productos, cada uno con 10–15 combinaciones de talla y color. El procesamiento de combinaciones tarda aproximadamente entre 3 y 5 veces más por producto.

Configuración recomendada:

  • Elementos del ciclo: 500
  • Número máximo de ciclos: 100
  • Fragmentos de procesamiento de productos (FPF_CHUNK_SIZE): 500 (ajusta al tamaño del ciclo para evitar cargar más en memoria de lo que se procesa)

Ejemplo: VPS sin límite de tiempo

Una tienda con 15.000 productos en un VPS donde max_execution_time es 0 o muy alto.

Configuración recomendada:

  • Elementos del ciclo: 0 (desactivado — generación en un único paso)
  • Intervalo de cron: cada 60 minutos

Desactivar los ciclos elimina la sobrecarga del encadenamiento cURL y simplifica la resolución de problemas.

Notas importantes

  • El modo ciclo es por tienda en configuraciones multitiendo, pero el campo Elementos del ciclo en sí se almacena como valor de configuración global y se aplica a todas las tiendas en una instalación multitienda.
  • Los feeds de overrides de idioma y país se generan después de que se complete el feed principal. También se benefician del modo ciclo, pero utilizan una frecuencia de ciclo de guardado separada controlada por FPF_FEED_UPDATE_OVERRIDES.
  • El archivo feeds/progress.json se escribe dentro de la carpeta feeds/ del módulo. Asegúrate de que el usuario del servidor web tiene permiso de escritura en esa carpeta.
  • El feed se sirve desde un archivo temporal durante la generación y se mueve a la ubicación definitiva solo al completarse. Si compruebas la URL del feed durante la generación, recibirás la versión completa anterior.
  • Al ejecutarse desde CLI (php_sapi_name() === 'cli'), el valor FPF_CYCLE no se carga: la generación por CLI siempre se ejecuta en modo de paso único independientemente de la configuración de Elementos del ciclo.

Resolución de problemas

ProblemaSolución
El feed siempre está vacío o incompletoEl tamaño del ciclo es demasiado grande para el límite de tiempo de tu servidor. Reduce Elementos del ciclo a 500 o menos y regenera.
El mensaje "Una generación de feed está en curso" aparece cada vez que inicias la generaciónUna generación anterior se bloqueó. Espera 120 segundos e inténtalo de nuevo. Si el problema se repite, comprueba que la carpeta feeds/ tiene permisos de escritura para que progress.json pueda actualizarse.
La barra de progreso del panel está bloqueada en un porcentajeEl proceso de generación fue interrumpido durante un ciclo. La barra refleja el último progress.json escrito. Inicia una nueva generación para reiniciar.
Límite de ciclos alcanzado, feed incompletoAumenta el Número máximo de ciclos en la pestaña Opciones de generación. Estima los ciclos necesarios como: (total de productos × número de feeds) ÷ tamaño del ciclo.
Errores de memoria durante la generaciónReduce Fragmentos de procesamiento de productos (FPF_CHUNK_SIZE) para disminuir el número de productos cargados en memoria a la vez durante el paso de carga de stock.
La generación se completa pero la URL del feed sigue mostrando datos antiguosEl feed no se movió porque la generación no se completó del todo. Comprueba la pestaña Errores en busca de errores de producto que puedan haber provocado la salida anticipada de la generación.
La generación por CLI ignora la configuración de Elementos del cicloEste es el comportamiento esperado. La CLI se ejecuta en paso único; el modo ciclo solo se aplica a solicitudes web y cron.

Preguntas frecuentes

¿Cómo sé si mi tienda necesita el modo ciclo?

Si tu tienda tiene más de 1.000 productos, o si anteriormente has visto un feed vacío o incompleto, deberías activar el modo ciclo. Empieza con un tamaño de ciclo de 1.000 y redúcelo si la generación sigue agotando el tiempo de espera.

¿El modo ciclo ralentiza la generación del feed en general?

Ligeramente. Cada ciclo añade una pequeña sobrecarga por la llamada cURL y la E/S del archivo de progreso. Para la mayoría de las tiendas, el tiempo total de generación aumenta entre un 5 y un 10% en comparación con el paso único. La compensación es la fiabilidad en servidores con límites de tiempo.

¿Qué ocurre con el feed en directo mientras la generación está en curso?

Nada cambia. La URL del feed en directo sirve el último feed completado hasta que la nueva generación finaliza y mueve el archivo temporal a su lugar definitivo. Tus clientes y Facebook no perciben ninguna interrupción.

Establecí el Número máximo de ciclos en 30 y guardé, pero aparece 50 en el formulario. ¿Es un error?

No. El valor mínimo permitido para este campo es 50. Si introduces un número inferior a 50, se eleva a 50 automáticamente al guardar. Lo mismo aplica al ciclo de guardado de overrides de productos (mínimo 10) y al ciclo de guardado de productos (mínimo 5).

¿Puedo ejecutar la generación desde la línea de comandos en lugar de usar cron?

Sí. Usa php index.php --fpf_secret_key=YOUR_KEY desde la raíz de PrestaShop. La generación por CLI siempre se ejecuta en paso único (el modo ciclo está desactivado en CLI). Esto es útil para catálogos muy grandes en servidores donde PHP CLI no tiene límite de tiempo.

¿Cada tienda en una configuración multitienda genera su feed de forma independiente?

Una única ejecución de generación procesa todas las tiendas habilitadas en secuencia dentro de la misma cadena de ciclos. Las tiendas que ya han finalizado se omiten automáticamente en los ciclos de continuación para no duplicar trabajo.

La barra de progreso del panel muestra el 100% pero la URL del feed devuelve productos antiguos. ¿Qué ha fallado?

Esto puede ocurrir si la carpeta feeds/ no tiene permisos de escritura, lo que impide que el archivo temporal se mueva a la ubicación definitiva. Verifica que el usuario del servidor web tiene permiso de escritura en /modules/facebookproductsfeed/feeds/.

Funcionalidades relacionadas