𝗛𝗼𝘄 𝗜 𝗕𝘂𝗶𝗹𝘁 𝗮 𝗦𝗲𝘁 𝗜𝘁 𝗮𝗻𝗱 𝗙𝗼𝗿𝗴𝗲𝘁 𝗜𝘁 𝗦𝘆𝗻𝗰 𝗦𝘆𝘀𝘁𝗲𝗺
ਉਤਪਾਦਾਂ ਦੀਆਂ ਕੀਮਤਾਂ ਕਈ ਥਾਵਾਂ 'ਤੇ ਬਦਲਦੀਆਂ ਹਨ। ਉਹ ਐਡਮਿਨ ਪੈਨਲ ਵਿੱਚ, ਬਲਕ ਇੰਪੋਰਟ (bulk imports) ਰਾਹੀਂ, ਜਾਂ API webhooks ਰਾਹੀਂ ਬਦਲਦੀਆਂ ਹਨ।
ਜੇਕਰ ਤੁਸੀਂ ਇਹਨਾਂ ਤਬਦੀਲੀਆਂ ਨੂੰ ਕਿਸੇ ਬਾਹਰੀ ਮਾਰਕੀਟਪਲੇਸ (external marketplace) ਨਾਲ ਸਿੰਕ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਇੱਕ ਸਮੱਸਿਆ ਦਾ ਸਾਹਮਣਾ ਕਰਨਾ ਪੈਂਦਾ ਹੈ। ਹਰ ਇੱਕ ਕੋਡ ਪਾਥ (code path) ਵਿੱਚ ਸਿੰਕ ਕਾਲ (sync call) ਜੋੜਨਾ ਇੱਕ ਗਲਤੀ ਹੈ। ਤੁਸੀਂ ਇੱਕ ਨੂੰ ਭੁੱਲ ਜਾਓਗੇ। ਤੁਸੀਂ ਇੱਕ ਨੂੰ ਤੋੜ ਦਿਓਗੇ। ਰੱਖ-ਰਖਾਅ (maintenance) ਇੱਕ ਭਿਆਨਕ ਮੁਸ਼ਕਲ ਬਣ ਜਾਂਦਾ ਹੈ।
Django signals ਇਸਦਾ ਹੱਲ ਕਰਦੇ ਹਨ। ਤੁਸੀਂ ਮਾਡਲ ਸੇਵ (model save) ਇਵੈਂਟ ਨਾਲ ਜੁੜ ਜਾਂਦੇ ਹੋ। ਇਹ ਇੱਕੋ ਥਾਂ 'ਤੇ ਹਰ ਤਬਦੀਲੀ ਨੂੰ ਫੜ ਲੈਂਦਾ ਹੈ।
ਪਰ signals ਵਿੱਚ ਇੱਕ ਖਾਮੀ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਇੱਕੋ ਵਾਰ ਵਿੱਚ 100 ਕੀਮਤਾਂ ਅਪਡੇਟ ਕਰਦੇ ਹੋ, ਤਾਂ signal 100 ਵਾਰ ਚੱਲਦਾ ਹੈ। ਇਹ 100 API calls ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਰੇਟ ਲਿਮਿਟਾਂ (rate limits) ਦਾ ਸਾਹਮਣਾ ਕਰੋਗੇ ਜਾਂ ਸਰੋਤਾਂ (resources) ਦੀ ਬਰਬਾਦੀ ਕਰੋਗੇ।
ਮੈਂ ਇਸਨੂੰ ਠੀਕ ਕਰਨ ਲਈ ਤਿੰਨ-ਭਾਗਾਂ ਵਾਲਾ ਪੈਟਰਨ ਵਰਤਦਾ ਹਾਂ:
• ਇੱਕ signal handler ਜੋ ਤੁਰੰਤ ਕਾਰਵਾਈ ਕਰਨ ਦੀ ਬਜਾਏ IDs ਇਕੱਠੀਆਂ ਕਰਦਾ ਹੈ।
• ਡੁਪਲੀਕੇਟਸ ਨੂੰ ਹਟਾਉਣ ਲਈ ਇੱਕ per-thread set।
• ਸਭ ਕੁਝ ਇੱਕੋ ਵਾਰ ਪ੍ਰੋਸੈਸ ਕਰਨ ਲਈ transaction.on_commit ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਇੱਕ flush callback।
ਇਹ ਇਸ ਤਰ੍ਹਾਂ ਕੰਮ ਕਰਦਾ ਹੈ।
threading.local()ਦੀ ਵਰਤੋਂ ਕਰੋ Global variable ਦੀ ਵਰਤੋਂ ਨਾ ਕਰੋ। Global variables ਰਿਕਵੈਸਟਾਂ (requests) ਵਿੱਚ ਸਟੇਟ ਸਾਂਝੀ ਕਰਦੇ ਹਨ। ਇਸ ਨਾਲ ਡਾਟਾ ਲੀਕੇਜ (data leakage) ਹੋ ਸਕਦੀ ਹੈ।threading.local()ਡਾਟਾ ਨੂੰ ਇੱਕ ਸਿੰਗਲ ਥ੍ਰੈਡ (single thread) ਤੱਕ ਸੀਮਤ ਰੱਖਦਾ ਹੈ।ਰਿਕਾਰਡ ਕਰੋ, ਕਾਰਵਾਈ ਨਾ ਕਰੋ Signal handler ਸਿਰਫ਼ ਉਤਪਾਦ ਦੀ ID ਨੂੰ ਇੱਕ set ਵਿੱਚ ਜੋੜਦਾ ਹੈ। ਫਿਰ ਇਹ Django ਨੂੰ ਦੱਸਦਾ ਹੈ ਕਿ ਡਾਟਾਬੇਸ ਟ੍ਰਾਂਜੈਕਸ਼ਨ (database transaction) ਸਫਲ ਹੋਣ ਤੋਂ ਬਾਅਦ ਹੀ flush ਫੰਕਸ਼ਨ ਚਲਾਵੇ। ਇਹ ਉਸ ਡਾਟਾ ਨੂੰ ਸਿੰਕ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ ਜੋ ਸੇਵ ਹੋਣ ਵਿੱਚ ਅਸਫਲ ਰਿਹਾ ਹੋਵੇ।
ਕੰਮ ਨੂੰ ਬੈਚ (batch) ਵਿੱਚ ਕਰੋ ਜਦੋਂ ਟ੍ਰਾਂਜੈਕਸ਼ਨ ਕਮਿਟ (commit) ਹੁੰਦੀ ਹੈ, ਤਾਂ flush ਫੰਕਸ਼ਨ ਚੱਲਦਾ ਹੈ। ਇਹ set ਦੀ ਕਾਪੀ ਬਣਾਉਂਦਾ ਹੈ ਅਤੇ ਇਸਨੂੰ ਸਾਫ਼ ਕਰ ਦਿੰਦਾ ਹੈ। ਫਿਰ ਇਹ IDs ਦੀ ਪੂਰੀ ਸੂਚੀ ਇੱਕ service layer ਨੂੰ ਭੇਜ ਦਿੰਦਾ ਹੈ।
Service layer ਸਾਰੇ ਉਤਪਾਦਾਂ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਇੱਕ ਬਲਕ ਕੁਐਰੀ (bulk query) ਕਰਦੀ ਹੈ। ਇਹ ਉਹਨਾਂ ਨੂੰ ਸਟੋਰ ਅਨੁਸਾਰ ਗਰੁੱਪ ਕਰਦੀ ਹੈ। ਅੰਤ ਵਿੱਚ, ਇਹ ਹਰੇਕ ਸਟੋਰ ਲਈ 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