मी 'Set It and Forget It' सिंक सिस्टम कशी तयार केली
उत्पादनांच्या किमती अनेक ठिकाणी बदलतात. त्या ॲडमिन पॅनेलमध्ये, बल्क इम्पोर्टद्वारे किंवा API वेबहुक्सद्वारे बदलल्या जाऊ शकतात.
जर तुम्हाला हे बदल बाह्य मार्केटप्लेसवर (external marketplace) सिंक करायचे असतील, तर तुम्हाला एका समस्येचा सामना करावा लागतो. प्रत्येक कोड पाथमध्ये (code path) सिंक कॉल जोडणे ही एक चूक आहे. तुम्ही एखादा विसरू शकता किंवा एखादा कोड बिघडू शकतो. यामुळे मेंटेनन्स (maintenance) करणे अत्यंत कठीण होते.
Django signals या समस्येवर उपाय देतात. तुम्ही मॉडेल 'save' इव्हेंटला हुक (hook) करू शकता. यामुळे प्रत्येक बदल एकाच ठिकाणी पकडला जातो.
पण signals मध्ये एक त्रुटी आहे. जर तुम्ही एकाच वेळी १०० किमती अपडेट केल्या, तर सिग्नल १०० वेळा फायर होतो. यामुळे १०० API कॉल्स ट्रिगर होतात. यामुळे तुम्ही रेट लिमिट्स (rate limits) ओलांडू शकता किंवा संसाधनांचा (resources) अपव्यय होऊ शकतो.
हे सुधारण्यासाठी मी तीन भागांच्या पॅटर्नचा वापर करतो:
• एक सिग्नल हँडलर जो लगेच कृती करण्याऐवजी फक्त IDs गोळा करतो.
• डुप्लिकेट्स काढण्यासाठी एक 'per-thread set'.
• सर्व काही एकाच वेळी प्रोसेस करण्यासाठी transaction.on_commit वापरून एक 'flush callback'.
ते कसे काम करते ते खाली दिले आहे.
threading.local()वापरा ग्लोबल व्हेरिएबल (global variable) वापरू नका. ग्लोबल व्हेरिएबल्स सर्व रिक्वेस्टमध्ये स्टेट शेअर करतात, ज्यामुळे डेटा लीक (data leakage) होऊ शकतो.threading.local()डेटा एका सिंगल थ्रेडपुरता मर्यादित ठेवते.रेकॉर्ड करा, कृती करू नका सिग्नल हँडलर फक्त प्रॉडक्ट ID एका 'set' मध्ये जोडतो. त्यानंतर, डेटाबेस ट्रान्झॅक्शन यशस्वी झाल्यानंतरच 'flush function' चालवण्यासाठी तो Django ला सांगतो. यामुळे जे डेटा सेव्ह होण्यात अपयशी ठरले आहे, ते सिंक होण्यापासून वाचते.
कामाचे बॅचिंग करा (Batch the work) जेव्हा ट्रान्झॅक्शन कमिट (commit) होते, तेव्हा 'flush function' चालते. ते 'set' ची कॉपी करते आणि मूळ 'set' क्लिअर करते. त्यानंतर ते सर्व IDs ची यादी 'service layer' कडे पाठवते.
'Service layer' सर्व उत्पादने मिळवण्यासाठी एकच 'bulk query' करते. ते स्टोअरनुसार त्यांचे गट (groups) करते. शेवटी, ते प्रत्येक स्टोअरसाठी Celery कडे एकच टास्क पाठवते.
याचे फायदे स्पष्ट आहेत:
- डुप्लिकेट्स काढणे (Deduplication) स्वयंचलित आहे. 'set' हे काम तुमच्यासाठी करते.
- ट्रान्झॅक्शन सेफ्टी (Transaction safety) अंगभूत आहे. तुम्ही कधीही 'rolled-back' झालेला डेटा सिंक करत नाही.
- कार्यक्षमता (Efficiency) उच्च आहे. तुम्ही N+1 क्वेरी समस्या टाळता.
- विश्वासार्हता (Reliability) उच्च आहे. जर API फेल झाले, तर Celery पुन्हा प्रयत्न (retries) करते.
तुम्ही ही सिस्टम एकदाच तयार करता. तुम्ही नंतर जोडलेले प्रत्येक नवीन फीचर आपोआप सिंक सिस्टमसोबत काम करते.
तुम्ही Django मध्ये बाह्य API सिंक कसे हाताळता? तुम्ही signals वापरता की दुसरा कोणता पॅटर्न?
स्त्रोत: https://dev.to/acel/how-i-built-a-set-it-and-forget-it-sync-system-with-django-signals-2ld7