2012-01-26 7 views
8

मेरे पास एक मोबाइल ऐप है जो एक अपाचे सर्वर पर संग्रहीत एक JSON फ़ाइल पढ़ता है। यदि एक जीयूआई के माध्यम से कुछ बदल जाता है तो उस JSON फ़ाइल की सामग्री पुन: उत्पन्न होती है (एक PHP स्क्रिप्ट का उपयोग कर)।क्या अपाचे उन्हें सेवा देने से पहले फ़ाइलों को रीड-लॉक करता है?

मुझे चिंता है कि इसके बाद में जेएसओएन फ़ाइल को ओवरराइट करने की कोशिश अपाचे द्वारा की जा रही है, जिससे समस्याएं हो सकती हैं।

क्या अपाचे फ़ाइलों की सेवा करने से पहले एक रीड लॉक प्राप्त करता है? यदि नहीं, तो क्या होगा यदि मैं इसे एक ही समय में लिखने की कोशिश करता हूं तो यह परोसा जा रहा है?

+0

क्या आपको वास्तव में 'भौतिक' फ़ाइल की आवश्यकता है या क्या आप केवल सामग्री को आउटपुट करके फ़ाइल को नकली कर सकते हैं? – PeeHaa

उत्तर

9

नहीं। POSIX- संगत सिस्टम पर, सभी ताले सलाहकार हैं, इसलिए यदि अपाचे को रीड लॉक मिलेगा, तो दूसरी प्रक्रिया केवल फाइल लिख सकती है।

आप निर्धारित कर सकते कि strace साथ:

[pid 7246] open("/var/www/file.json", O_RDONLY|O_CLOEXEC) = 11 
[pid 7246] fcntl(11, F_GETFD)   = 0x1 (flags FD_CLOEXEC) 
[pid 7246] mmap(NULL, 20, PROT_READ, MAP_SHARED, 11, 0) = 0x7f53f93da000 
[pid 7246] munmap(0x7f53f93da000, 20) = 0 
[pid 7246] writev(10, [{"HTTP/1.1 200 OK\r\nDate: Thu, 26 J"}, ...) = 365 
[pid 7246] close(11)     = 0 

इसलिए, यह हो सकता है कि आपके JSON फ़ाइल केवल आंशिक रूप से लिखा है। इस समस्या से बचने के लिए, अपनी JSON फ़ाइल को एक ही फाइल सिस्टम पर एक अस्थायी फ़ाइल में लिखें, और फ़ाइल को ओवरराइट करने के लिए परमाणु rename का उपयोग करें।

इस तरह, यदि open सफल हो गया है, तो अपाचे पुरानी फ़ाइल की सेवा जारी रखेगा। यदि renameopen से पहले समाप्त होता है, तो अपाचे को नई, पूर्ण फ़ाइल मिल जाएगी।

यदि आप स्थिरता (बिजली विफलता के मामले में) के बारे में चिंता करते हैं, तो आप उस एप्लिकेशन में fsync पर कॉल करना भी चाहेंगे जो JSON फ़ाइल को बंद करने से पहले लिखता है।

+0

अगर मैंने PHP के http://php.net/manual/en/function.flock.php का उपयोग किया और एक लेखन लॉक मिला, तो क्या यह ठीक रहेगा? – cdmckay

+0

@cdmckay नहीं, एक लेखन लॉक का कोई प्रभाव नहीं पड़ता है, क्योंकि अपाचे को रीड लॉक नहीं मिलता है। मैंने जवाब बढ़ाया। संक्षेप में: ['नाम बदलें] का उपयोग करें (http://php.net/rename)। – phihag

+0

जिज्ञासा से, अपाचे उन्हें रीड-लॉक क्यों नहीं करता? प्रदर्शन? – cdmckay

1

आप * निक्स प्लेटफ़ॉर्म के लिए गलत प्रतिमान में सोच रहे हैं। आप जो चाहते हैं वह परमाणु फ़ाइल आपकी स्क्रिप्ट में JSON फ़ाइल को लिखती है। आप फ़ाइल को पुराने निर्देशिका में स्थानांतरित करने के लिए rename() का उपयोग करके लक्ष्य निर्देशिका में एक अद्वितीय अस्थायी फ़ाइल नाम पर फ़ाइल लिखकर ऐसा करते हैं। फ़ाइल चाल ऑपरेशन परमाणु है। असीमित प्रक्रियाएं या तो पुरानी JSON फ़ाइल या नई खोलेंगी लेकिन एक संकर नहीं।

अस्थायी फ़ाइल नाम बनाने के कई तरीके हैं। tempnam() पर PHP दस्तावेज़ उपयोगकर्ता टिप्पणियां देखें। मेरा सिस्टम एक अनुरोध अद्वितीय आईडी उत्पन्न करता है, इसलिए मैं आधार के रूप में $_SERVER["UNIQUE_ID"] का उपयोग करता हूं।