Tunny एक Golang पुस्तकालय है जिसका उपयोग goroutines पूल बनाने और प्रबंधित करने के लिए किया जा सकता है, जिससे आप संगतिशील API का उपयोग करके किसी भी संख्या की goroutines से काम की परिमाणित कर सकते हैं।

जब आपका काम किसी भी असंकेत स्रोत से आता है लेकिन आपकी समकक्ष प्रसंस्करण क्षमता सीमित है, तो एक निश्चित goroutine पूल अत्यंत उपयोगी होता है। उदाहरण के लिए, CPU-भारी HTTP अनुरोध नौकरियों की प्रसंस्करण करते समय, आप CPU की संख्या के बराबर आकार का एक पूल बना सकते हैं।

स्थापना

go get github.com/Jeffail/tunny

अन्यथा, dep का उपयोग करके:

dep ensure -add github.com/Jeffail/tunny

उपयोग

अधिकांश मामलों के लिए, आपका भारी काम एक सरल func() द्वारा प्रस्तुत किया जा सकता है, जिसके लिए आप NewFunc का उपयोग कर सकते हैं। चलिए देखते हैं कि हम कैसे CPU गणना के एक HTTP अनुरोध के उदाहरण का उपयोग करते हैं:

package main

import (
	"io/ioutil"
	"net/http"
	"runtime"

	"github.com/Jeffail/tunny"
)

func main() {
	numCPUs := runtime.NumCPU()

	pool := tunny.NewFunc(numCPUs, func(payload interface{}) interface{} {
		var result []byte

		// TODO: पायलोड का उपयोग करके कुछ CPU-भारी परिचालन कार्य करें

		return result
	})
	defer pool.Close()

	http.HandleFunc("/work", func(w http.ResponseWriter, r *http.Request) {
		input, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "आंतरिक त्रुटि", http.StatusInternalServerError)
		}
		defer r.Body.Close()

		// इस काम को हमारे पूल में आयात करें। यह कॉल संगतिशील है और कार्य पूरा होने तक ब्लॉक होगा।
		result := pool.Process(input)

		w.Write(result.([]byte))
	})

	http.ListenAndServe(":8080", nil)
}

Tunny यहाँ टाइमआउट का समर्थन भी करता है। आप ऊपर दिए गए Process कॉल को निम्नलिखित कोड से बदल सकते हैं:

result, err := pool.ProcessTimed(input, time.Second*5)
if err == tunny.ErrJobTimedOut {
	http.Error(w, "अनुरोध समय समाप्त हो गया", http.StatusRequestTimeout)
}

आप समय सीमा और अंत्यसमय को संभालने के लिए अनुरोध सन्दर्भ (या किसी अन्य संदर्भ) का उपयोग कर सकते हैं। बस Process कॉल को निम्नलिखित कोड से बदलें:

result, err := pool.ProcessCtx(r.Context(), input)
if err == context.DeadlineExceeded {
	http.Error(w, "अनुरोध समय समाप्त हो गया", http.StatusRequestTimeout)
}

पूल का आकार संशोधित करना

आप SetSize(int) का उपयोग करके किसी भी समय Tunny पूल का आकार बदल सकते हैं।

pool.SetSize(10) // 10 goroutines
pool.SetSize(100) // 100 goroutines

यह भी सुरक्षित है यदि अन्य goroutines अभी भी प्रसंस्करण कर रहे हों।

स्थायी Goroutine

कभी-कभी, Tunny पूल में प्रत्येक goroutine को अपनी व्यवस्था राज्य की आवश्यकता होती है। उस मामले में, आपको tunny.Worker का अनुसरण करना चाहिए, जिसमें समाप्ति, अंतर्रुद्धि (यदि कोई काम समय सीमित हो जाता है और अब आवश्यक नहीं है), और अगले कार्य की आवंटन को ब्लॉक की आवश्यकता के लिए कॉल शामिल होती है।

Worker प्रकार के साथ पूल बनाते समय, आपको अपने कस्टम अनुमान प्राप्त करने के लिए एक निर्माता प्रदान करना होता है:

pool := tunny.New(poolSize, func() Worker {
	// TODO: हर goroutine के लिए राज्य आवंटन करने का कार्य यहाँ पर व्यावसायिक करें।
	return newCustomWorker()
})

इस तरह, Tunny पूल आकार परिवर्तन होने पर Worker प्रकार के निर्माण और नाश को साफ कर सकता है।

क्रमबद्धता

पिछाड़ी स्थिति में बांकागणित कार्यों को क्रम में प्रसंस्कृत करने की गारंटी नहीं है। वर्तमान कम संचालन की वजह से चैनल और चयन वर्गों के वर्तमान कारण से पिछाड़ी कार्य स्टैक को कुंजी रूप में प्रसंस्कृत किया जाएगा। हालांकि, यह व्यवहार नकारात्मक समाप्ति का हिस्सा नहीं है और इस पर निर्भर करना नहीं चाहिए।