ServiceProvider::optimizes() puedes incorporar los comandos de generación y eliminación a los comandos optimize y optimize:clear de Laravel.
Esta página parte de los fundamentos del desarrollo de paquetes y revisa la implementación de Laravel Framework v13.35.0. No trata el formato de los archivos de caché, sino el contrato de registro y de operación.
Separar el registro de comandos del registro de tareas
commands() registra las clases de comando que se pueden invocar desde Artisan. optimizes() es un proceso distinto que registra como tareas de optimización nombres de comandos que ya son ejecutables. Si solo llamas al segundo, las clases de comando no quedan registradas.
El siguiente ejemplo asume que el paquete ya implementa CacheMetadataCommand y ClearMetadataCommand, y que sus $signature son courier:cache y courier:clear-cache, respectivamente.
optimizes() son nullable, así que puedes registrar solo la generación o solo la eliminación. Aun así, indica siempre a los usuarios con qué procedimiento se invalida la caché generada.
La clave de registro también es un contrato con el usuario
ServiceProvider guarda los comandos de generación en el array estático $optimizeCommands y los de eliminación en $optimizeClearCommands. En ambos casos, key se usa como clave del array.
Si omites key, el nombre se genera a partir del nombre de clase del provider. Por ejemplo, CourierServiceProvider da courier. Como solo se usa el nombre de la clase, pueden producirse colisiones incluso con providers del mismo nombre en otros espacios de nombres.
Si vuelves a registrar la misma clave, el comando de ese lado se sobrescribe con el valor posterior. Si quieres registrar varias tareas, usa claves distintas. Evita también las claves de las tareas estándar de Laravel, como config o routes, porque al combinar las tareas estándar con las del paquete, las claves de texto iguales también se sobrescriben.
Se ejecutan después de las tareas estándar
En la implementación revisada, ambos comandos expanden el array registrado por los paquetes sobre el array de tareas estándar y luego las invocan en orden. Si usas una clave que no colisiona, las tareas del paquete se añaden después de las estándar.
Partiendo de este orden, el comando de generación no debe reconstruir otras cachés estándar, sino generar solo los datos que pertenecen al paquete. No uses
optimizes() como API para controlar el orden de dependencias entre varios paquetes: si necesitas un orden estricto, enumera explícitamente los comandos específicos.
Excluir por clave o por nombre de comando
La opción--except de ambos comandos acepta valores separados por comas. Se eliminan los espacios al principio y al final de cada valor, y se excluyen las tareas cuya clave o nombre de comando coincida.
cache:clear estándar. cache es la clave de la tarea, no un nombre propio del paquete.
La exclusión solo afecta a esa ejecución. No es una configuración que desactive el registro del provider ni que elimine automáticamente una caché del paquete creada anteriormente.
Distinguir el FAIL de una tarea del código de salida del comando padre
OptimizeCommand y OptimizeClearCommand invocan cada tarea con callSilently() y pasan a la visualización de la tarea si el código de salida es 0. Como la salida normal de los comandos hijos no se muestra, para investigar la causa ejecuta directamente el comando específico.
En Laravel v13.35.0, ninguno de los dos handle() devuelve como valor de retorno del padre el código distinto de cero que devuelva un comando hijo. Aunque se muestre FAIL en pantalla, el bucle continúa y, si no hay excepciones, el código de salida del comando padre es 0. En cambio, las excepciones lanzadas se vuelven a lanzar en el componente de visualización de tareas, así que no siguen el mismo comportamiento de continuar.
Si la generación del paquete es un requisito obligatorio del despliegue, usa un procedimiento que permita comprobar directamente el código de salida del comando hijo. Por ejemplo, a continuación se excluye la tarea del paquete de la ejecución conjunta y se ejecuta directamente una sola vez después de las tareas estándar.
courier:cache, pero no agrega las salidas distintas de cero de las tareas estándar. En despliegues que también necesiten detectar con rigor los fallos de las tareas estándar, ejecuta por separado los comandos necesarios y comprueba sus códigos de salida.
Diseño y verificación de una caché que resista las actualizaciones
Además del registro, define también las responsabilidades de los comandos y del lado que lee la caché.- La generación debe llevar al mismo estado a partir de la misma entrada aunque se ejecute repetidamente, y no debe activar datos incompletos si falla a mitad del proceso.
- La eliminación debe completarse correctamente aunque no exista caché, y no debe borrar la configuración publicada ni los datos persistentes del usuario.
- Un comando cuya generación falle debe informar del error y devolver un valor distinto de cero. El lado que lee tampoco debe tratar incondicionalmente como válida una caché dañada.
- Si cambias el formato de la caché, indica a los usuarios que deben regenerarla y considera también reiniciar los procesos de larga duración.
Páginas relacionadas
Fusión y caché de la configuración de paquetes
Repasa cómo se completan los valores de la configuración publicada y su relación con la reconstrucción de la caché de configuración.
Probar paquetes Laravel con Orchestra Testbench
Registra providers y comandos Artisan en el entorno de pruebas.
Fuentes primarias consultadas
- Documentación oficial de Laravel: Optimize commands
- ServiceProvider: optimizes() y la clave de registro
- OptimizeCommand: tareas y proceso de exclusión
- OptimizeClearCommand: tareas de eliminación y orden de ejecución
- Command: valor de retorno de handle() y código de salida
- Task: visualización del resultado y relanzamiento de excepciones