Чому прищеплюють події не один раз


13

Це запитання виникає з іншого, яке я поставив перед Stackoverflow . Я використовую Watcher - ті ж самі проблеми стосуються і Incron - для контролю за папкою та її дочірніми папками щодо змін та мовчки перебирати ці зміни в Dropbox.

Я стежу за write_closeподією - IN_CLOSE_WRITE- з метою. Спочатку я спостерігав за modifyподією, тобто IN_MODIFY. Хоча це працювало, я виявив, що при написанні великих файлів він буде спрацьовувати не один раз. Це звучало справедливо, тому я перейшов, IN_CLOSE_WRITEоскільки відчув, що справедливо вважати, що для даного файлу це відбудеться лише один раз.

Однак це не так. Навіть для дуже невеликого текстового файлу - всього одного символу - створеного в Nano, подія відбувається два рази. У кращому випадку це може призвести до зайвого трафіку, коли один і той же файл синхронізується на Dropbox два рази. У моєму випадку це призводить до катастрофи, оскільки в перший захід я здійснюю синхронізацію, а потім видаляю файл на стороні сервера. Результат - у другій події файл сторони Dropbox стає 0-байтним файлом.

Я зараз маю справу з цим, змушуючи сценарій синхронізації спати протягом 10 секунд, перш ніж робити щось інше, а потім перевіряю, чи існує відповідний файл до спроби синхронізації Dropbox. Це працює, тому що при другій ітерації файл відсутній, а сценарій просто припиняється.

Це в кращому випадку звучить хакі. Можливо, це не поганий злом, але я хотів би зрозуміти - чому ж навіть IN_CLOSE_WRITEподія трапляється не один раз?


Деякі додаткові відомості

  • Перевірте, чи не існує декількох примірників запуску вахти.

Вихід від ps ax|grep watcher.py

23880 ?        Sl     0:01 python /usr/local/bin/watcher.py restart
24977 pts/0    S+     0:00 grep --color=auto watcher.py

Файлова система є ext4. Я мушу зазначити, що я стикався з точно тим же питанням з Incron. Я запускаю демон Watcher з пакетного сценарію, виконаного через /etc/rc2.d. Incron OTH запускається без будь-якого мороку через його apt-get install incronвстановлення за замовчуванням .


Суть мого watcher.iniфайлу наведена нижче.

[DEFAULT]
logfile=/var/log/watcher.log
pidfile=/var/run/watcher.pid

[job1]
watch=/path/to/watch

events=write_close
excluded=
recursive=true
autoadd=true

command=/home/datastore.php $filename

Я зменшив datastore.phpсценарій до найголовнішого, щоб переконатися, що він запускається двічі без будь-якого з моїх брудних завантажень Dropbox + вихідний код видалення.

#! /usr/bin/php
<?php
file_put_contents('/tmp/watcher',$argv[1],FILE_APPEND);

?>

Потім я створив невеликий файл на шляху, про який йде мова, а потім вивчив /tmp/watcher. Проблема все ще зберігається - у файлі все ще є дві послідовні записи для $argv[1].


1
Я спробував багато варіантів, але не можу дублювати вашу проблему з декількома стрільбами IN_CLOSE_WRITE. Все, що я робив, спричиняє одиночний вихід із заміна. Я буду продовжувати намагатися. Але поки лише питання. Яка файлова система? Ext4? Інший?
lornix

@lornix - перегляньте правки до мого питання. Файлова система є, ext4і я впевнений, що у мене немає двох екземплярів роботи Watcher. Я зіткнувся з тим же питанням з Incron.
DroidOS

Ви сказали: "Я виконую синхронізацію, а потім видаляю файл на сервері". Чи це видалення викликає другу подію? Чи можете вимкнути deleteрутину та спробувати ще раз?
Гермар

@Germar - дивіться правки до мого питання. Навіть якщо сценарій синхронізації не виконує справжню синхронізацію, і unlinkпроблема не зберігається
DroidOS

Вибачте, швидше за все ідеї, я не можу відтворити проблему на жодному зі своїх машин. Я отримую одну подію, не більше. Щось інше бере участь, щось не згадується. У вас встановлений антивірус? щось подібне?
lornix

Відповіді:


1

Я не впевнений, але, швидше за все, перший write_close записує в нього атрибути файлів, як час створення, і лише після цього він записує фактичні дані. Насправді rsync створює тимчасовий файл, і коли все зроблено, він переміщує тимчасовий файл у фактичний файл у тій самій папці, так що легко контролювати, як це нормально створюється, коли ви використовуєте rsync, а переміщення - це атомна операція. З іншого боку, є щось, що викликає один вистріл в інотифікованому, ймовірно, що за допомогою цього ми можемо запустити щось у першому повідомленні про модифікацію, і як ви запропонували заснути протягом розумного часу, перш ніж почати операцію. Я зараз копаю це, і оновлюсь, коли знайду щось нове. /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


Ви, можливо, поклали палець на щось цілком дійсне тут. Це зажадає певного розслідування. Дякую за пораду. Я відправлю ще раз, якщо виявлю, що це якимось чином проблема.
DroidOS

Я не думаю, що ATTRIB щось додає у сам файл, я помилявся.
Едік Мкоян

0

У мене недостатньо представників, щоб розмістити це як коментар, але ви впевнені, що тимчасові, можливо, приховані файли не створюються? У мене була схожа проблема із inotifywaitзапуском декількох разів, але я зрозумів, що це тому, що при редагуванні vim створить .swp-файл, який запустить подію при закритті. Він також підбере подію закриття з оригінального файлу.

Схоже, ви помічаєте подію, що випускає кілька файлів у один і той же файл, що я не зміг відтворити - це відбудеться лише один раз для тимчасового файлу та один раз для оригіналу.

Я спробував швидкий тест з nano, і я не думаю, що він взагалі створює тимчасовий файл (принаймні, для випадку з декількома символами), але чи є ще щось у вашій установці, що може розраховувати на подібну поведінку?


дякую за ваші пропозиції. Я зіткнувся з проблемою inotify multiple, навіть коли я створюю тривіальний 1-байтовий файл з Nano - або навіть просто перенаправляючи одну конфігурацію з консолі у файл. "Вирішення", яке я окреслив у своєму первісному запитанні, поки що мене продовжує. Однак, в довгостроковій перспективі єдиним рішенням я повинен відновити свій сервер починаючи з нуля, щоб виявити, коли починається помилка - моє налаштування з Incron, Watcher (до цього це сталося, коли я щойно Incron), MariaDB, Nginx, Redis, Memcached ... не зовсім "простий".
DroidOS

Про всяк випадок перевірте, чи не стежите за тією ж папкою двічі. Якщо ні, то, наприклад, коли я копіюю файл у спільну частину самби через клієнт os x samba, це відбувається create, close_write, видалити, створити, close_write Коли я це роблю з клієнтом Windows, це виглядає більш розумним створенням, write_close і більше нічого. Тому я вирішую свою проблему, відстежуючи першу модифікацію файлу за допомогою цього каталогу IN_MODIFY, IN_ONESHOT /. спати кілька команд часу тим, що робить це.
Едік Мкоян
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.