Dirijo una empresa de integración continua alojada y ejecutamos el código de nuestros clientes en Linux. Cada vez que ejecutamos el código, lo ejecutamos en una máquina virtual separada. Un problema frecuente que surge es que las pruebas de un cliente a veces fallarán debido al pedido del directorio de su código desprotegido en la VM.
Déjame entrar en más detalles. En OSX, el sistema de archivos HFS + garantiza que los directorios se recorran siempre en el mismo orden. Los programadores que usan OSX asumen que si funciona en su máquina, debe funcionar en todas partes. Pero a menudo no funciona en Linux, porque los sistemas de archivos de Linux no ofrecen garantías de pedido al recorrer directorios.
Como ejemplo, considere que hay 2 archivos, a.rb, b.rb. a.rb define MyObject
, y b.rb usa MyObject
. Si a.rb se carga primero, todo funcionará. Si b.rb se carga primero, intentará acceder a una variable indefinida MyObject
y fallará.
Pero peor que esto, es que no siempre falla. Debido a que el sistema de archivos que ordena en Linux no está ordenado, será un orden diferente en diferentes máquinas. Esto es peor porque a veces las pruebas pasan y otras fallan. Este es el peor resultado posible.
Entonces mi pregunta es, ¿hay alguna manera de hacer que el pedido del sistema de archivos sea repetible? ¿Alguna bandera a ext4 quizás, que dice que siempre atravesará directorios en algún orden? ¿O tal vez un sistema de archivos diferente que tenga esta garantía?
fuente
Respuestas:
Sé que no es la respuesta que está buscando, pero creo que la solución correcta es evitar depender del orden de los archivos en un directorio. Tal vez siempre sea consistente en todos los sistemas de archivos HFS +, y tal vez podría encontrar una manera de hacerlo consistente en ext4 o en algún otro sistema de archivos, pero a la larga le costará más problemas de los que ahorrará. Alguien más que use su aplicación se encontrará con una desagradable sorpresa cuando no se dé cuenta de que solo es compatible con algunos tipos de sistemas de archivos y no con otros. El orden puede cambiar si se restaura un sistema de archivos desde la copia de seguridad. Es probable que tenga problemas de compatibilidad porque el orden consistente de HFS + y el orden consistente ext4 podrían no ser los mismos.
Simplemente lea todas las entradas del directorio y ordene la lista lexicográficamente antes de usarla. Al igual que
ls
hace.Usted menciona archivos
a.rb
yb.rb
, pero si estamos hablando de archivos fuente de lenguaje de programación, ¿no debería cada archivo ya ser responsable de garantizar que importe todas sus dependencias?fuente
La llamada POSIX en Linux readdir () no garantiza ningún orden consistente. Si desea resultados ordenados, la aplicación que maneja los archivos es responsable de ordenar cómo se presentan a las funciones de llamada.
/programming/8977441/does-readdir-guarantee-an-order
Ahora, dado que usted dijo que este era el código de su cliente y no puede solucionarlo, podría alterar las bibliotecas vinculadas que se utilizan para proporcionar una llamada readdir () consistente. Eso requeriría algo de trabajo y valdría la pena su propia pregunta. Para una referencia rápida a eso, consulte http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .
Alterar esto podría generar algunas otras series completas de problemas que quizás no pueda prever. Se le recomienda encarecidamente, pero puede ser una solución si su cliente no puede recibir una educación adecuada.
fuente
Informe a su cliente que existe una dependencia de orden inherente que debe establecerse explícitamente. Ofrezca ayudar al cliente a expresar la dependencia de tal manera que una compilación funcione en todos los sistemas y haga que el cliente adopte el flujo modificado que captura la dependencia del orden de compilación.
Si el cliente desea poder compilar en otras máquinas, sería muy grosero de su parte pensar que es gratis.
fuente
Linux moderno (ext4) agrega un índice de árbol B para listas de archivos. Uno de sus efectos es que el orden de los archivos predeterminados depende de un hash de sus nombres.
Para deshabilitar esta función, use:
fuente