सिंक इंजन कैसे काम करता है
यह पेज WCPOS v1.10.0 में पेश किए गए सिंक इंजन का वर्णन करता है। पुराने संस्करण एक अलग, प्रति-स्क्रीन रेप्लिकेशन मॉडल का उपयोग करते हैं — इस पेज के अंत में v1.10.0 में क्या बदला देखें।
WCPOS लोकल-फ़र्स्ट है: हर स्क्रीन डिवाइस पर मौजूद एक डेटाबेस से पढ़ती और उसमें लिखती है, और एक सिंक इंजन पृष्ठभूमि में उस डेटाबेस तथा आपके WooCommerce स्टोर को एक-दूसरे के अनुरूप बनाए रखता है। यह पेज बताता है कि इंजन कैसे तय करता है कि क्या लाना है, कब लाना है, और आपकी बिक्री सर्वर तक वापस कैसे पहुँचती है — विवरण का वह स्तर जो डेवलपर, इंटीग्रेटर और उन स्टोर मालिकों के लिए उपयोगी है जो समझना चाहते हैं कि POS उनकी होस्टिंग के साथ क्या कर रहा है।
प्रति स्टोर और कैशियर एक इंजन
POS हर डिवाइस पर प्रति साइट + स्टोर + कैशियर संयोजन एक सिंक इंजन चलाता है। वह इंजन अपना स्वयं का लोकल डेटाबेस रखता है, इसलिए स्टोर या कैशियर बदलने पर पूरा डेटा-प्लेन बदल जाता है, न कि किसी एक साझा ढेर के रिकॉर्ड फ़िल्टर होते हैं। प्रति-कैशियर अलगाव जानबूझकर रखा गया है: एक ही डिवाइस पर दो कैशियर कभी भी लोकल डेटा साझा नहीं करते।
अपग्रेड पर लोकल डेटाबेस कभी भी उसी जगह माइग्रेट नहीं किए जाते — ऐप एक नया डेटाबेस शुरू करता है और सर्वर से दोबारा डाउनलोड करता है, जिसके पास हमेशा आधिकारिक प्रति होती है (v1.9 से अपग्रेड करना देखें)।
Pro मल्टी-स्टोर इंस्टॉल पर हर सिंक अनुरोध अपने स्टोर की पहचान बताता है, इसलिए काउंटर पर संपादित किया गया मूल्य उसी स्टोर का मूल्य अपडेट करता है, वेब स्टोर का नहीं।
पृष्ठभूमि में क्या चलता है
इंजन जो कुछ भी एक निर्धारित समय-सारणी पर करता है, वह एक लेन है — पृष्ठभूमि कार्य की एक नामित, सीमाबद्ध इकाई। लेन तीन समूहों में आती हैं:
| समूह | लेन | डिफ़ॉल्ट लय |
|---|---|---|
| पुल | परिवर्तन जाँच (परिवर्तन संकेत) | 10 से – 5 मिनट, आपके सिंक प्रीसेट द्वारा निर्धारित |
| हालिया ऑर्डर, उत्पाद कैटलॉग सीड, संदर्भ डेटा सीड | ~5 मिनट | |
| ग्राहक ट्रिकल (केवल निष्क्रिय समय में) | ~5 मिनट | |
| पुश | राइट ड्रेन — कतारबद्ध लोकल परिवर्तन भेजता है | ~10 से |
| रखरखाव | अखंडता और विलोपन ऑडिट, सर्वर कुल का रिफ़्रेश | कुछ मिनटों से लेकर ~17 मिनट तक |
हर लेन पर दो गुण लागू होते हैं:
- हर लेन प्रति-रन अनुरोध सीमा घोषित करती है। कोई भी लेन एक ही रन में असीमित संख्या में अनुरोध नहीं फैला सकती; बड़े कार्य पुनः-आरंभ योग्य कर्सर के साथ सीमाबद्ध बैचों में चलते हैं। यह एक मूल डिज़ाइन अपरिवर्तनीयता है, जिसे सिंक प्रदर्शन में विस्तार से समझाया गया है।
- रखरखाव कैशियर को रास्ता देता है। ऑडिट और पृष्ठभूमि प्राइम उस इंटरैक्टिव कार्य के बाद चलते हैं जो किसी काउंटर को बिक्री के लिए तैयार करता है, उससे पहले कभी नहीं, और जब आपका सर्वर दबाव के संकेत दिखाता है तो सबसे पहले इन्हीं को रोका जाता है।
ऊपर दी गई लय डिफ़ॉल्ट हैं। जाँच अंतराल और प्रति-अनुरोध रिकॉर्ड की संख्या को POS में स्टोर हेल्थ → प्रदर्शन से प्रति डिवाइस व्यापारी स्वयं समायोजित कर सकता है — देखें स्टोर हेल्थ।
POS को परिवर्तनों का पता कैसे चलता है
इंजन यह जानने के लिए डेटा दोबारा डाउनलोड नहीं करता कि वह बदला या नहीं। सर्वर एक परिवर्तन लॉग रखता है, और POS एक हल्की परिवर्तन जाँच पोल करता है जो केवल एक सवाल का जवाब देती है: मेरी पिछली स्थिति के बाद से क्या कुछ आगे बढ़ा है?
- एक जाँच आठ संग्रहों को कवर करती है — उत्पाद, विविधताएँ, कर दरें, ग्राहक, कूपन, श्रेणियाँ, ब्रांड और टैग। ऑर्डर जानबूझकर परिवर्तन जाँच में नहीं हैं; ऑर्डर की ताज़गी उसकी अपनी हालिया-ऑर्डर लेन से आती है, यही कारण है कि उत्पाद और ऑर्डर अपडेट अलग-अलग लय में पहुँच सकते हैं।
- एक निष्क्रिय काउंटर की लागत लगभग शून्य होती है। इंजन सशर्त अनुरोध भेजता है: जब कुछ नहीं बदला होता, तो सर्वर बिना बॉडी वाला एक अकेला
304 Not Modifiedलौटाता है। एक शांत स्टोर प्रति जाँच एक छोटे-से उत्तर पर स्थिर हो जाता है। - जाँचों में ±20% जिटर होता है, ताकि एक ही साइट के कई रजिस्टर एक साथ तालमेल में विस्फोट करने के बजाय अलग-अलग समय पर बँट जाएँ।
- निष्क्रियता क्षय: बिना किसी इंटरैक्शन के 10 मिनट बीतने पर जाँचें फैल जाती हैं (60 सेकंड की न्यूनतम सीमा तक)। कोई भी वास्तविक गतिविधि — एक स्पर्श, एक कीप्रेस, एक स्वीकृत बारकोड स्कैन — तुरंत पूरी लय पर लौट आती है और एक तत्काल कैच-अप जाँच चलाती है। क्षय अंतराल को केवल बढ़ाता है; यह कभी भी कॉन्फ़िगर की गई सेटिंग से तेज़ पोल नहीं करता।
- कई दिनों से बंद पड़ा काउंटर इतिहास दोहराने के बजाय नया आधार बनाता है। यदि परिवर्तन लॉग काउंटर की अंतिम स्थिति से बहुत आगे बढ़ चुका है, तो हर पंक्ति को दोहराने में सैकड़ों अनुरोध लगेंगे। इसके बजाय इंजन अपना कर्सर सिरे तक ले जाता है और डिवाइस के पास जो पहले से है उसकी वर्तमान सर्वर स्थिति दोबारा जाँचता है — इसलिए लागत लोकल प्रति के आकार के अनुसार बढ़ती है, न कि इस बात के अनुसार कि काउंटर कितने समय तक दूर रहा।
स्क्रीनों को उनका डेटा कैसे मिलता है
v1.10.0 में स्क्रीनें अपना सिंक स्वयं नहीं चलातीं। एक स्क्रीन घोषित करती है कि वह क्या दिखा रही है — खोज शब्द, फ़िल्टर, क्रम, पेज — और इंजन तय करता है कि इसके लिए कोई अनुरोध चाहिए भी या नहीं। हर घोषणा तीन में से किसी एक तरीके से हल होती है:
- लाया गया — इंजन ने इसे पूरा करने के लिए नेटवर्क पर काम किया।
- लोकल रूप से पूरा किया गया — डिवाइस के पास उत्तर पहले से था, या एक समान हालिया फ़ेच इसे कवर कर लेता है।
- अधिक्रमित — स्क्रीन आगे बढ़ गई (आपने स्क्रॉल किया, फ़िल्टर बदला) और एक नई घोषणा ने उसकी जगह ले ली। यह सामान्य है, त्रुटि नहीं।
जिस फ़िल्टर का उत्तर केवल लोकल रूप से दिया जा सकता है, वह कभी सर्वर तक नहीं जाता। और किसी घोषणा का सफल होना यह नहीं दर्शाता कि कोई संग्रह पूरी तरह डाउनलोड हो चुका है — पूर्णता अलग से ट्रैक की जाती है (अगला अनुभाग)।
सब कुछ पहले से डाउनलोड नहीं किया जाता, और बूट के समय डिवाइस पर क्या मौजूद रहता है, यह संग्रह के अनुसार बदलता है:
- सीड किया गया — उत्पाद एक सीमाबद्ध कैटलॉग सीड के ज़रिए भरते हैं; कर दरें बूट पर खींची जाती हैं (उनके बिना POS कार्ट की गणना नहीं कर सकता)।
- माँग पर, साथ में एक निष्क्रिय ट्रिकल — ग्राहकों के लिए कोई अग्रिम सीड नहीं है। ग्राहक ट्रिकल प्रति निष्क्रिय अंतराल एक छोटा बैच डाउनलोड करता है, और कैशियर के सक्रिय रहने पर पूरी तरह छोड़ दिया जाता है; नए या बदले हुए ग्राहक परिवर्तन जाँच के माध्यम से आते हैं।
- पहली बार खोलने पर लाया गया — श्रेणियाँ, टैग, ब्रांड और कूपन तब खींचे जाते हैं जब कोई कैशियर उन्हें पहली बार खोलता है। जिस संग्रह को कोई नहीं खोलता, वह कभी एक भी अनुरोध उत्पन्न नहीं करता।
विविधता चयनकर्ता प्रति बार खुलने पर मूल्य और स्टॉक को एक बार अतिरिक्त रूप से रिफ़्रेश करते हैं, ताकि पहले से मौजूद विविधता तुरंत रेंडर हो लेकिन कभी कई दिन पुराना स्टॉक न दिखाए।
„क्या सब कुछ डाउनलोड हो गया?" — ईमानदार कवरेज
„5,000 में से 1,240 उत्पाद" जैसे पाठ को हर के लिए एक सर्वर-पक्ष कुल चाहिए। इंजन हर संग्रह के लिए एक ऐसा कुल बनाए रखता है (लगभग हर 15 मिनट में रिफ़्रेश किया जाता है, और आमतौर पर मुफ़्त — वास्तविक सिंक प्रतिक्रियाएँ पहले से यह कुल साथ लाती हैं, इसलिए किसी अलग अनुरोध की ज़रूरत कम ही पड़ती है) और एक सख़्त ईमानदारी अनुबंध का पालन करता है:
- पुराना या अनुपलब्ध सर्वर कुल जाँचा जा रहा है… के रूप में दिखाया जाता है — कभी भी चुपचाप लोकल गिनती से नहीं बदला जाता। लोकल हर हमेशा 100% पढ़ेगा और ठीक उसी अंतर को छिपा देगा जिसे उजागर करने के लिए यह संख्या मौजूद है।
- जब इंजन पूर्णता की गारंटी नहीं दे सकता, तो निर्णय अज्ञात होता है और UI उस आँकड़े को लोकल गिनती के रूप में लेबल करता है।
- ऑर्डर कवरेज बार पूरे सर्वर ऑर्डर इतिहास के सापेक्ष मापता है, जबकि काउंटर जानबूझकर केवल खुले और हालिया ऑर्डर रखता है — इसलिए एक स्वस्थ काउंटर वहाँ डिज़ाइन के अनुसार आंशिक दिखता है।
ये संख्याएँ स्टोर हेल्थ → डेटाबेस पर दिखाई देती हैं, साथ में एक बिक्री के लिए तैयार पड़ाव भी, जो पहला उत्पाद डिवाइस पर आते ही चालू हो जाता है — ऑफ़लाइन होना इसे नहीं रोकता, क्योंकि ऑफ़लाइन बेचना ही तो मकसद है। देखें स्टोर हेल्थ।
परिवर्तन आपके स्टोर तक वापस कैसे पहुँचते हैं
हर लोकल राइट — एक बिक्री, एक उत्पाद संपादन, एक ग्राहक अपडेट — पहले डिवाइस पर मौजूद एक टिकाऊ आउटबाउंड कतार में आता है, और एक ड्रेन लेन हर कुछ सेकंड में उस कतार को WooCommerce तक धकेलती है। यही ऑफ़लाइन बिक्री को सुरक्षित बनाता है: बिना कनेक्शन के की गई बिक्री कतार में रुकी रहती है और कनेक्शन लौटने पर निकल जाती है।
महत्वपूर्ण विवरण:
- कार्ट राइट प्रति ऑर्डर क्रमबद्ध होते हैं। तेज़ी से चलने वाले स्कैनर बर्स्ट एक-एक करके लागू होते हैं, और दोबारा जोड़ा गया आइटम दूसरी पंक्ति कतार में डालने के बजाय उसी पंक्ति में मिल जाता है जिसकी वह नकल है।
- ऑर्डर पावतियाँ सर्वर की प्रति को अपनाती हैं। WooCommerce बनाते समय ऑर्डर लाइन आइटम को ID देता है; इंजन स्वीकृत ऑर्डर को अपना लेता है ताकि बाद के अपडेट उन्हीं पंक्तियों से मेल खाएँ, न कि डुप्लिकेट जोड़ें। यह अपनाना संकोची है — यह कभी भी उस लोकल संपादन को नहीं मिटाता जिसे सर्वर ने देखा ही नहीं, और केवल ऑर्डर पर लागू होता है।
- जिस राइट को सर्वर स्थायी रूप से अस्वीकार कर देता है, उसे कभी चुपचाप दोबारा नहीं आज़माया जाता। उसे सर्वर के अपने कारण के साथ अलग रख दिया जाता है और स्टोर हेल्थ → डेटाबेस पर „ऐसे परिवर्तन जो कभी आपके सर्वर तक नहीं पहुँचे" के रूप में दिखाया जाता है, दो स्पष्ट क्रियाओं के साथ: दोबारा भेजें (रिकॉर्ड की मौजूदा स्थिति से अनुरोध दोबारा बनाता है, ताकि बाद में किए गए सुधार लागू हों) और हटाएँ। कोई स्वचालित पुनःप्रयास लूप नहीं है — रिकवरी हमेशा एक दृश्यमान, सोच-समझकर की गई क्रिया होती है। व्यापारी के लिए विस्तृत मार्गदर्शन के लिए स्टोर हेल्थ देखें।
कई ब्राउज़र टैब
एक ही स्टोर के वेब POS को कई टैब में चलाना समर्थित है। हर टैब बिक्री दर्ज कर सकता है — राइट साझा कतार में जुड़ते हैं — लेकिन हर स्टोर + कैशियर स्कोप के लिए भेजने का काम एक चुना हुआ टैब करता है। यदि वह टैब बंद हो जाए, तो ब्राउज़र अपने-आप अगले टैब को पदोन्नत कर देता है। अलग-अलग कैशियर के रूप में साइन-इन दो टैब अलग स्कोप हैं और प्रत्येक अपनी कतार स्वयं संभालता है।
लोकल स्टोरेज
वेब और डेस्कटॉप ऐप डेटा को एक OPFS (Origin Private File System) वर्कर के ज़रिए संग्रहीत करते हैं; iOS और Android ऐप एक फ़ाइलसिस्टम इंजन के माध्यम से वही ऑन-डिस्क फ़ॉर्मैट उपयोग करते हैं। चारों प्लेटफ़ॉर्म एक ही स्टोरेज फ़ॉर्मैट और वही करप्शन-रिकवरी टूलिंग साझा करते हैं। (पुराने संस्करण वेब पर IndexedDB और नेटिव पर SQLite उपयोग करते थे।)
क्वेरी डेटाबेस परत के भीतर ही चलती हैं — सिलेक्टर, सॉर्ट और पेज — इसलिए पंक्तियों का केवल दिखाई देने वाला पेज ही ऐप तक पहुँचता है। 10,000 ऑर्डर वाले एक कृत्रिम फ़िक्स्चर पर, इस पुशडाउन ने एक सक्रिय सब्सक्रिप्शन के तहत प्रति-राइट अपडेट लागत को ~27 ms से घटाकर ~0.06 ms कर दिया।
v1.9 से अपग्रेड करना
v1.10.0 लोकल डेटाबेस को माइग्रेट नहीं करता — यह एक कोल्ड रीसिंक करता है:
- पहली बार शुरू होने पर ऐप एक नया लोकल डेटाबेस खोलता है और आपके स्टोर से दोबारा डाउनलोड करता है। हर डिवाइस पर एक बार पूरा पुनः-डाउनलोड होने की अपेक्षा रखें।
- कुछ भी नहीं खोता: सभी सिंक किए गए डेटा की आधिकारिक प्रति आपके WooCommerce सर्वर के पास है। लंबित, बिना भेजे परिवर्तन पुराने डेटा की सफ़ाई से पहले भेजे जाते हैं या सामने लाए जाते हैं — अपग्रेड किसी बिना भेजी गई बिक्री को नष्ट नहीं कर सकता।
- ऐप और प्लगइन एक साथ जारी होते हैं। v1.10.0 क्लाइंट प्लगइन के v2 सिंक API की भाषा बोलते हैं। यदि केवल एक पक्ष अपग्रेड हुआ हो, तो अनुरोध
rest_no_routeत्रुटियों के साथ विफल होते हैं — इस हस्ताक्षर का मतलब है „दूसरे हिस्से को अपडेट करें", न कि कोई टूटा हुआ इंस्टॉल।
v1.10.0 में क्या बदला
| v1.9.x | v1.10.0 | |
|---|---|---|
| सिंक की इकाई | प्रति माउंट की गई स्क्रीन क्वेरी एक रेप्लिकेशन स्ट्रीम | प्रति साइट + स्टोर + कैशियर एक इंजन |
| फ़ेच किससे चलता है | स्क्रीन का माउंट होना | स्क्रीन का यह घोषित करना कि उसे क्या चाहिए |
| परिवर्तन पहचान | नियमित पोल + हर घंटे पूरा ऑडिट | सशर्त 304 प्रतिक्रियाओं के साथ परिवर्तन लॉग कर्सर |
| सर्वर कुल | ट्रैक नहीं किए जाते थे | ईमानदार जाँचा जा रहा है… स्थितियों के साथ प्रति-संग्रह कुल |
| विफल राइट | अपारदर्शी ढंग से दोबारा आज़माए जाते थे | टिकाऊ कतार, दृश्यमान रिकवरी पैनल, कोई चुपचाप पुनःप्रयास नहीं |
| मल्टी-टैब वेब | असमन्वित | प्रति स्कोप एक चुना हुआ प्रेषक |
| लोकल खोज | शब्द-उपसर्ग मिलान | सबस्ट्रिंग मिलान (न्यूनतम 3 वर्ण) |
| स्टोरेज | IndexedDB (वेब), SQLite (नेटिव) | सभी प्लेटफ़ॉर्म पर OPFS-फ़ॉर्मैट स्टोरेज |
| सिंक ट्यूनिंग | निश्चित | स्टोर हेल्थ में प्रति-डिवाइस प्रीसेट और डायल |
इंजन के पीछे के प्रदर्शन दर्शन के लिए — अनुरोध सीमाएँ, सर्वर दबाव में बैक-ऑफ़, और मापे गए आँकड़े — देखें सिंक प्रदर्शन।