Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

308
Visualizações
Faltan eventos de inotify (en el directorio .git)

Estoy viendo archivos en busca de cambios usando eventos de inotificación (como sucede, desde Python, llamando a libc).

Para algunos archivos durante una git clone , veo algo extraño: veo un evento IN_CREATE , y veo a través de ls que el archivo tiene contenido, sin embargo, nunca veo IN_MODIFY o IN_CLOSE_WRITE . Esto me está causando problemas porque me gustaría responder a IN_CLOSE_WRITE en los archivos: específicamente, para iniciar una carga del contenido del archivo.

Los archivos que se comportan de manera extraña están en el .git/objects/pack y terminan en .pack o .idx . Otros archivos que crea git tienen una IN_CREATE -> IN_MODIFY -> IN_CLOSE_WRITE más regular (no estoy buscando eventos IN_OPEN ).

Esto está dentro de la ventana acoplable en MacOS, pero he visto evidencia de lo mismo en la ventana acoplable en Linux en un sistema remoto, por lo que sospecho que el aspecto de MacOS no es relevante. Estoy viendo esto si viendo y git clone están en el mismo contenedor acoplable.

Mis preguntas:

  • ¿Por qué faltan estos eventos en estos archivos?

  • ¿Qué se puede hacer al respecto? Específicamente, ¿cómo puedo responder a la finalización de escrituras en estos archivos? Nota: idealmente, me gustaría responder cuando la escritura esté "terminada" para evitar cargar innecesariamente/(incorrectamente) la escritura "inacabada".


Editar: leyendo https://developer.ibm.com/tutorials/l-inotify/ parece que lo que veo es consistente con

  • un archivo temporal separado, con un nombre como tmp_pack_hBV4Alz , que se crea, modifica y cierra;
  • se crea un enlace fijo a este archivo, con el nombre final .pack ;
  • se elimina el nombre original tmp_pack_hBV4Alz .

Creo que mi problema, que es tratar de usar inotify como disparador para cargar archivos, luego se reduce a notar que el archivo .pack es un enlace fijo a otro archivo y, en este caso, ¿se está cargando?

over 4 years ago · Santiago Trujillo
5 Respostas
Responde à pergunta

0

Puedo especular que Git la mayor parte del tiempo usa actualizaciones de archivos atómicos que se hacen así:

  1. El contenido de un archivo se lee en la memoria (y se modifica).
  2. El contenido modificado se escribe en un archivo separado (normalmente ubicado en el mismo directorio que el original y con un nombre aleatorio (estilo mktemp ).
  3. El nuevo archivo entonces se rename(2) d -d sobre el original; esta operación garantiza que cada observador que intente abrir el archivo usando su nombre obtendrá el contenido antiguo o el nuevo.

Tales actualizaciones son vistas por inotify(7) como moved_to , ya que un archivo "reaparece" en un directorio.

over 4 years ago · Santiago Trujillo Relatório

0

Según esta respuesta aceptada , supongo que podría haber alguna diferencia en los eventos según el protocolo que se utiliza (es decir, ssh o https).

¿Observa el mismo comportamiento al monitorear la clonación desde el sistema de archivos local con la --no-hardlinks ?

 $ git clone git@github.com:user/repo.git # set up watcher for new dir $ git clone --no-hardlinks repo new-repo

Su comportamiento observado al ejecutar el experimento en un host Linux y Mac probablemente elimine este problema abierto siendo la causa https://github.com/docker/for-mac/issues/896 pero agregando solo por si acaso.

over 4 years ago · Santiago Trujillo Relatório

0

Para responder a su pregunta por separado para git 2.24.1 en Linux 4.19.95:

  • ¿Por qué faltan estos eventos en estos archivos?

No ve los eventos IN_MODIFY / IN_CLOSE_WRITE porque git clone siempre intentará usar enlaces duros para archivos en el directorio .git/objects . Al clonar a través de la red oa través de los límites del sistema de archivos, estos eventos volverán a aparecer.

  • ¿Qué se puede hacer al respecto? Específicamente, ¿cómo puedo responder a la finalización de escrituras en estos archivos? Nota: idealmente, me gustaría responder cuando la escritura esté "terminada" para evitar cargar innecesariamente/(incorrectamente) la escritura "inacabada".

Para detectar la modificación de enlaces duros, debe configurar un controlador para el evento CREATE de inotify que sigue y realiza un seguimiento de esos enlaces. Tenga en cuenta que un simple CREATE también puede significar que se creó un archivo no vacío. Luego, en IN_MODIFY / IN_CLOSE_WRITE a cualquiera de los archivos, también debe activar la misma acción en todos los archivos vinculados. Obviamente, también debe eliminar esa relación en el evento DELETE .

Probablemente, un enfoque más simple y más robusto sería hacer un hash periódico de todos los archivos y verificar si el contenido de un archivo ha cambiado.


Corrección

Después de verificar de cerca el código fuente de git y ejecutar git con strace , descubrí que git usa archivos mapeados en memoria, pero principalmente para leer contenido. Vea el uso de xmmap que siempre se llama solo con PROT_READ . . Por lo tanto, mi respuesta anterior a continuación NO es la respuesta correcta. Sin embargo, con fines informativos, todavía me gustaría mantenerlo aquí:

  • No ve eventos IN_MODIFY porque packfile.c usa mmap para acceder a archivos e inotify no informa modificaciones para archivos mmap ed.

    Desde la página de manual de inotify :

    La API de inotify no informa sobre los accesos a archivos y las modificaciones que pueden ocurrir debido a mmap(2), msync(2) y munmap(2).

over 4 years ago · Santiago Trujillo Relatório

0

Hay otra posibilidad (del hombre inotify):

Tenga en cuenta que la cola de eventos puede desbordarse. En este caso, los eventos se pierden. Las aplicaciones robustas deberían manejar la posibilidad de eventos perdidos con gracia. Por ejemplo, puede ser necesario reconstruir parte o la totalidad de la memoria caché de la aplicación. (Un enfoque simple, pero posiblemente costoso, es cerrar el descriptor de archivo de inotify, vaciar el caché, crear un nuevo descriptor de archivo de inotify y luego volver a crear entradas de vigilancia y caché para los objetos a monitorear).

Y aunque git clone puede generar un gran flujo de eventos, esto puede suceder.

Cómo evitar esto:

  1. Aumente el búfer de lectura, pruebe con fcntl(F_SETPIPE_SZ) (este enfoque es una suposición, nunca lo he intentado).
  2. Lea eventos en un búfer grande en un hilo dedicado, procese eventos en otro hilo.
over 4 years ago · Santiago Trujillo Relatório

0

Tal vez cometiste el mismo error que yo cometí hace años. Solo he usado inotify dos veces. La primera vez, mi código simplemente funcionó. Más tarde, ya no tenía esa fuente y comencé de nuevo, pero esta vez me faltaban eventos y no sabía por qué.

Resulta que cuando estaba leyendo un evento, en realidad estaba leyendo un pequeño lote de eventos. Analicé el que esperaba, pensando que eso era todo, eso era todo. Eventualmente, descubrí que hay más en los datos recibidos, y cuando agregué un pequeño código para analizar todos los eventos recibidos de una sola lectura, no se perdieron más eventos.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda