تُنی گولینگ کتابخانہ ہے جو گوروٹین پول بنانے اور مسلسل طریقے سے گوروٹینوں کی تعداد استعمال کر کے کسی بھی تعداد کے گوروٹین سے کام محدود کرنے کی اجازت دیتی ہے۔
جب آپ کا کام کسی بھی تعداد کی بے ترتیبی ذرائع سے آئی ہو، مگر آپ کی متوازی کارروائی کی قابلیت محدود ہو، تو ایک مضبوط گوروٹین پول بے حد فائدہ مند ہوتا ہے۔ مثال کے طور پر، جب CPU-انٹینسو HTTP درخواست کے کام کو عمل کرتے وقت، آپ CPUوالے تعداد کے پول بنا سکتے ہیں۔
نصب (Installation)
go get github.com/Jeffail/tunny
یا phir dep استعمال کرتے ہوئے:
dep ensure -add github.com/Jeffail/tunny
استعمال (Usage)
اکثر مواقع پر، آپ کا بھاری کام ایک سادہ func()
سے دیا جا سکتا ہے، جس کے وقت آپ NewFunc
کا استعمال کر سکتے ہیں۔ چلیں دیکھتے ہیں کہ ہمارے اس مثال کے HTTP درخواستوں کو CPU گنتی کے لئے کیسے استعمال کیا جاتا ہے:
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: payload کا استعمال کرتے ہوئے کچھ 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, "Internal error", http.StatusInternalServerError)
}
defer r.Body.Close()
// اس کام کو ہمارے پول میں شامل کریں۔ یہ دعوت مسلسل ہے اور اس کا انتظار کرے گا جب تک کام مکمل نہ ہو جائے۔
result := pool.Process(input)
w.Write(result.([]byte))
})
http.ListenAndServe(":8080", nil)
}
تُنی کو وقت کی حد میں بھی حمایت فراہم ہے۔ آپ یہاں سے یوپی اوپی کال کو مندرجہ ذیل کوڈ کے ساتھ بدل سکتے ہیں:
result, err := pool.ProcessTimed(input, time.Second*5)
if err == tunny.ErrJobTimedOut {
http.Error(w, "Request timed out", http.StatusRequestTimeout)
}
آپ توقیت اور مقدار کے حوالے سے طلب کو سنبھالنے کے لئے درخواست کے ساتھ درخواست سنت کال (یا کسی دوسری سنت) کا استعمال کر سکتے ہیں۔ سادہ طور پر 'Process' کال کو مندرجہ ذیل کوڈ کے ساتھ بدلیں:
result, err := pool.ProcessCtx(r.Context(), input)
if err == context.DeadlineExceeded {
http.Error(w, "Request timed out", http.StatusRequestTimeout)
}
پول کا سائز:
آپ SetSize(int)
کا استعمال کرکے کسی بھی وقت تنی کے پول کا سائز تبدیل کر سکتے ہیں۔
pool.SetSize(10) // 10 گوروٹینز
pool.SetSize(100) // 100 گوروٹینز
یہ بہترین ہوتا ہے حتی کہ دیگر گوروٹینز کام پر ہوں۔
حالتی گوروٹین
کبھی کبھی، تنی پول میں ہر گوروٹین کو اپنی منظم حالت کی ضرورت ہوتی ہے۔ اس صورت میں، آپ کو tunny.Worker
کا تعریف کرنا ہوگا، جس میں خاتمہ، رکاوٹ (اگر درخواست کا وقت ختم ہو گیا ہے اور وہ زیادہ ضرورت نہیں ہے) اور اگلے درخواست کی تجویز تک مخصوص معیار کے لمحے تک کالز شامل ہوں گے۔
پول کو یں dyo Worker
قسم کے ساتھ بناتے وقت، آپ کو اپنی خود کی تعمیر کنندہ فراہم کرنے کی ضرورت ہوتی ہے:
pool := tunny.New(poolSize, func() Worker {
//TODO: ہر گوروٹین کے لئے اسٹیٹ کی تخصیص کرنے کاعمل
return newCustomWorker()
})
اس طریقے سے، تُنی پول سائز تبدیل ہونے پر Worker
قسم کی تخلیق اورتہہ کرنے کا عمل کو صاف کر سکتا ہے۔
ترتیب:
درج درخواستیں منظور کرنے کی گارنٹی نہیں ہے۔ موجودہ ایمپلیمنٹیشن کی بنا پر چینل اور منتخب بلاک کی وجہ سے درج درخواستوں کے مصوغ کا کام FIFO قط (پہلا آیا، پہلا کھلا۔ اس کا رویہ تشریح کا حصہ نہیں ہے اور اس پر اعتماد نہیں کیا جانا چاہئے۔