Go में टास्क कतारों के साथ काम करना: शुरुआती लोगों के लिए
\n\nटास्क कतारें (task queues) आधुनिक विकास में मूलभूत पैटर्न में से एक हैं। Go (Golang) में, यह तंत्र अंतर्निहित समवर्ती प्रिमिटिव: गोरूटीन और चैनलों के कारण विशेष रूप से सुंदर ढंग से लागू होता है। इस लेख में, हम सरल उदाहरणों से लेकर उन्नत तकनीकों तक, Go में टास्क कतारें बनाने का तरीका समझेंगे।
\n\nटास्क कतार क्या है और इसकी आवश्यकता क्यों है?
\n\nटास्क कतार एक डेटा संरचना है जो FIFO (फर्स्ट इन, फर्स्ट आउट — "पहले आया, पहले गया") सिद्धांत पर काम करती है। कैश काउंटर पर एक कतार की कल्पना करें: पहला ग्राहक सेवा प्राप्त करता है, फिर दूसरा, और इसी तरह। प्रोग्रामिंग में, यह अनुमति देता है:
\n\n- \n
- कार्यों के आगमन और उनके प्रसंस्करण को अलग करना \n
- एक साथ निष्पादित संचालन की संख्या को सीमित करना \n
- हैंडलरों के बीच लोड को समान रूप से वितरित करना \n
- मुख्य थ्रेड को ब्लॉक किए बिना पृष्ठभूमि में कार्यों को संसाधित करना \n
Go अपने समवर्ती मॉडल के कारण कतारों को लागू करने के लिए आदर्श है। कई भाषाओं के विपरीत, जहाँ एक बाहरी लाइब्रेरी (जैसे RabbitMQ या Redis) की आवश्यकता होती है, Go में आप कोड की कुछ पंक्तियों में एक सरल टास्क कतार बना सकते हैं।
\n\nGo चैनलों पर एक सरल टास्क कतार बनाना
\n\nटास्क कतार को लागू करने का सबसे सरल तरीका बफ़र्ड चैनल का उपयोग करना है। आइए एक बुनियादी उदाहरण देखें:
\n\npackage main\n\nimport (\n "fmt"\n "time"\n)\n\nfunc worker(tasks <-chan string, id int) {\n for task := range tasks {\n fmt.Printf("वर्कर %d ने कार्य शुरू किया: %s\\n", id, task)\n time.Sleep(1 * time.Second) // कार्य का अनुकरण\n fmt.Printf("वर्कर %d ने कार्य पूरा किया: %s\\n", id, task)\n }\n}\n\nfunc main() {\n tasks := make(chan string, 5) // 5 कार्यों के लिए बफ़र्ड चैनल\n\n // 2 वर्कर शुरू करें\n for i := 1; i <= 2; i++ {\n go worker(tasks, i)\n }\n\n // कतार में कार्य भेजें\n for i := 1; i <= 10; i++ {\n tasks <- fmt.Sprintf("कार्य संख्या %d", i)\n }\n\n close(tasks) // सभी कार्य भेजने के बाद चैनल बंद करें\n time.Sleep(2 * time.Second) // पूरा होने के लिए समय दें\n}\n\nइस उदाहरण में:
\n- \n
- चैनल
tasksकतार के रूप में कार्य करता है \n - दो वर्कर (गोरूटीन) लगातार चैनल सुनते हैं और कार्यों को संसाधित करते हैं \n
- आकार 5 का बफर तत्काल प्रसंस्करण के बिना 5 कार्यों को भेजने की अनुमति देता है \n
वर्कर पूल पैटर्न: स्केलेबल प्रसंस्करण
\n\nवर्कर पूल (worker pool) एक सरल कतार का विकास है। एक निश्चित संख्या में वर्कर के बजाय, हम एक पूल बनाते हैं जिसे गतिशील रूप से स्केल किया जा सकता है। यह पैटर्न विशेष रूप से इसके लिए उपयोगी है:
\n\n- \n
- HTTP अनुरोधों का प्रसंस्करण \n
- डेटा का बैच प्रसंस्करण \n
- बाहरी API के साथ काम करना (एक साथ अनुरोधों की संख्या को सीमित करना) \n
यहाँ एक संरचना का उपयोग करके अधिक उन्नत कार्यान्वयन है:
\n\npackage main\n\nimport (\n "fmt"\n "sync"\n "time"\n)\n\ntype Task struct {\n ID int\n Payload string\n}\n\ntype WorkerPool struct {\n tasks chan Task\n results chan string\n wg sync.WaitGroup\n workers int\n}\n\nfunc NewWorkerPool(workers int) *WorkerPool {\n return &WorkerPool{\n tasks: make(chan Task, 100),\n results: make(chan string, 100),\n workers: workers,\n }\n}\n\nfunc (wp *WorkerPool) Start() {\n for i := 1; i <= wp.workers; i++ {\n wp.wg.Add(1)\n go wp.worker(i)\n }\n}\n\nfunc (wp *WorkerPool) worker(id int) {\n defer wp.wg.Done()\n for task := range wp.tasks {\n result := fmt.Sprintf("वर्कर %d ने कार्य %d पूरा किया: %s", \n id, task.ID, task.Payload)\n time.Sleep(500 * time.Millisecond) // कार्य का अनुकरण\n wp.results <- result\n }\n}\n\nfunc (wp *WorkerPool) AddTask(task Task) {\n wp.tasks <- task\n}\