เหตุใดจึงไม่แจ้งเหตุการณ์ที่เกิดขึ้นมากกว่าหนึ่งครั้ง


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เกิดเหตุการณ์มากกว่าหนึ่งครั้ง?


ข้อมูลเพิ่มเติมบางส่วน

  • ตรวจสอบเพื่อให้แน่ใจว่าไม่มี Watcher ทำงานอยู่หลายอินสแตนซ์

ผลผลิตจาก 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

@Germar - ดูการแก้ไขคำถามของฉัน แม้ว่าสคริปต์การซิงค์จะไม่มีการซิงค์จริงและunlinkยังคงมีปัญหาอยู่
DroidOS

ขออภัยแทนที่จะเป็นความคิดฉันไม่สามารถสร้างปัญหาขึ้นบนเครื่องของฉัน ฉันได้รับหนึ่งเหตุการณ์ไม่มาก มีบางอย่างเกี่ยวข้องเกี่ยวข้องกับบางสิ่งที่ไม่ได้กล่าวถึง คุณติดตั้งโปรแกรมป้องกันไวรัสหรือไม่? อะไรเช่นนั้น
lornix

คำตอบ:


1

ฉันไม่แน่ใจ แต่ส่วนใหญ่น่าจะเป็น write_close แรกที่เขียนแอ็ตทริบิวต์ไฟล์ลงในนั้นเช่นเวลาสร้างและหลังจากนั้นก็จะเขียนข้อมูลจริง ในความเป็นจริง rsync สร้างไฟล์ temp และเมื่อทุกอย่างเสร็จแล้วมันจะย้ายไฟล์ temp ไปยังไฟล์จริงในโฟลเดอร์เดียวกันดังนั้นจึงเป็นเรื่องง่ายที่จะตรวจสอบได้ถูกสร้างขึ้นตามปกติเมื่อคุณใช้ rsync และการย้ายเป็นการทำงานแบบปรมาณู ในทางกลับกันมีบางสิ่งบางอย่างที่เรียกว่า inotify อาจจะเป็นไปได้ว่าการใช้ที่เราสามารถทริกเกอร์บางอย่างในข้อความที่แก้ไขครั้งแรกและตามที่คุณแนะนำให้เข้าสู่โหมดสลีปตามเวลาที่เหมาะสม ฉันกำลังขุดสิ่งนี้อยู่และจะอัปเดตเมื่อพบสิ่งใหม่ /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


คุณอาจวางนิ้วลงบนสิ่งที่ค่อนข้างถูกต้องที่นี่ มันจะต้องมีการสอบสวน ขอบคุณสำหรับทิป. ฉันจะโพสต์กลับในกรณีที่ฉันพบว่านี่เป็นปัญหา
DroidOS

ฉันไม่คิดว่า ATTRIB จะเพิ่มอะไรลงไปในไฟล์เองฉันคิดผิด
Edik Mkoyan

0

ฉันมีตัวแทนไม่เพียงพอที่จะโพสต์สิ่งนี้เป็นความคิดเห็น แต่คุณแน่ใจหรือไม่ว่าไฟล์ชั่วคราวอาจซ่อนไม่ได้ถูกสร้างขึ้น? ฉันมีปัญหาคล้ายกันกับinotifywaitการยิงหลายครั้ง แต่ฉันรู้ว่าเป็นเพราะกลุ่มจะสร้างไฟล์. swp เมื่อทำการแก้ไขซึ่งจะเริ่มเหตุการณ์เมื่อปิด มันจะรับเหตุการณ์ปิดจากไฟล์ต้นฉบับ

ดูเหมือนว่าคุณจะสังเกตเห็นเหตุการณ์ที่ยิงไฟล์หลายไฟล์ในไฟล์เดียวกันซึ่งไม่ใช่สิ่งที่ฉันสามารถทำซ้ำได้ - สิ่งนี้จะเกิดขึ้นเพียงครั้งเดียวสำหรับไฟล์ชั่วคราวและหนึ่งครั้งสำหรับต้นฉบับ

ฉันลองทดสอบอย่างรวดเร็วกับ nano และฉันไม่คิดว่ามันจะสร้างไฟล์ temp เลย (อย่างน้อยก็ในบางกรณีของตัวละคร) แต่มีอะไรอีกบ้างในการตั้งค่าของคุณที่สามารถพึ่งพาพฤติกรรมที่คล้ายคลึงกันได้หรือไม่


ขอขอบคุณสำหรับคำแนะนำของคุณ. ฉันได้วิ่งเข้าไปในinotifyปัญหาหลายแม้ในขณะที่ผมสร้างไฟล์ 1 ไบต์จิ๊บจ๊อยมากกับนาโน - หรือแม้กระทั่งโดยเพียงแค่การเปลี่ยนเส้นทางถ่านเดียวจากคอนโซลลงในไฟล์ "การแก้ปัญหา" ที่ฉันได้ระบุไว้ในคำถามเดิมของฉันคือการทำให้ฉันไปในขณะนี้ อย่างไรก็ตามในระยะยาวทางออกเดียวที่ฉันต้องสร้างเซิร์ฟเวอร์ของฉันเริ่มต้นจากศูนย์เพื่อระบุเมื่อเกิดข้อผิดพลาด - การติดตั้งของฉันกับ Incron, Watcher (btw มันเกิดขึ้นเมื่อฉันมีเพียง Incron), MariaDB, Nginx, Redis, Memcached ... ไม่ใช่ "ง่ายๆ"
DroidOS

ในกรณีให้ตรวจสอบอีกครั้งหากคุณไม่ได้ตรวจสอบโฟลเดอร์เดียวกันสองครั้ง ถ้าไม่เช่นนั้นเมื่อฉันคัดลอกไฟล์ไปยังการแบ่งปันแซมบ้าผ่านไคลเอนต์ OS x แซมบ้าสิ่งนี้เกิดขึ้นสร้าง, close_write, ลบ, สร้าง, close_write เมื่อฉันทำเช่นนั้นกับไคลเอนต์ Windows มันดูสมเหตุสมผลมากขึ้นสร้าง write_close และไม่มีอะไรเพิ่มเติม ดังนั้นฉันจึงแก้ปัญหาของฉันโดยการตรวจสอบการแก้ไขครั้งแรกของไฟล์ด้วย IN_MODIFY, IN_ONESHOT / ไดเรกทอรีนี้ sleep คำสั่ง someTime คำสั่ง oneshot ทำสิ่งนั้น
Edik Mkoyan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.