Tunny হল একটি Golang লাইব্রেরি যা গোরোউটিন পুল তৈরি এবং পরিচালনা করার জন্য, যা আপনাকে সিঙ্ক্রোনাস API ব্যবহার করে যেকোনো সংখ্যক গোরোউটিন থেকে কাজের সীমা বৃদ্ধির দ্বারা প্রতিস্থাপন জন্য অনুমতি দেয়।

যখন আপনার কাজগুলি যোগাযোগ অসিঞ্চিত উৎস হতে পারে এবং তবে আপনার সমল প্রসেসিং সক্ষমতা সীমিত, তবে একটি নির্দিষ্ট গোরোউটিন পুল অত্যন্ত কার্যকর। উদাহরণস্বরূপ, CPU-intensive HTTP অনুরোধ কাজ প্রসেস করার সময়, আপনি CPU সংখ্যার মাপের মাধ্যমে পুল সাজাতে পারেন।

ইনস্টলেশন

go get github.com/Jeffail/tunny

বা, dep ব্যবহার করে:

dep ensure -add github.com/Jeffail/tunny

ব্যবহার

সবগুলি ক্ষেত্রের জন্য, আপনার ভারী কাজটি একটি সহজ 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: Perform some CPU-intensive operations using payload

		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 গোরোউটিন
pool.SetSize(100) // 100 গোরোউটিন

আপনি যদি অন্য গোরোউটিন এর জন্য এখনও প্রসেসিং ছিলে তবে এটা সুরক্ষিত।

অবস্থানিক গোরোউটিন

কিছুসময়, এগুলির প্রতিটি গোরোউটিন Tunny পুলে নিজের ব্যবস্থায় হতে পারে। ঐ ক্ষেত্রে, আপনি বাহ্যিক ম্যানেজমেন্ট স্টেট যাতে আপনাকে নিয়ে গোরোউটিন প্রয়োজন, তাহলে, আপনার নিজের বৈশিষ্ট্য অনুপ্রাণিত করা উচিত tunny.Worker বিবেচনা করতে পারেন, যেটি বিদায়কেরের ক্ষেত্রে ওলটাই, অনুপ্রাণিত এবং পরের কাজের বর্জনের উক্তিসহ।

Worker ধরনের পুল সৃষ্টি করার সময়, আপনার কাস্টম অনুপ্রাণিতিকরণ উৎপাদনের জন্য একটি নির্মাতা প্রদান করতে হবে:

pool := tunny.New(poolSize, func() Worker {
	// প্রতিটি গোরোউটিনের জন্য আপনার অবস্থা আরডার দিন.
	return newCustomWorker()
})

এই ভাবে, Tunny পরিবর্তন হলে, Worker ধরনের নির্মাণ এবং ধ্বংস করতে পারবে।

অর্ডারিং

পিছে পড়ে থাকা কাজগুলি আদেশে প্রসেস করা না কি নিশ্চিত না। চ্যানেল এবং সিলেক্ট ব্লকের বর্তমান ব্যবস্থার কারণে, পিছে পড়া কাজের স্ট্যাকগুলি একটি FIFO কিউ হিসাবে প্রসেস করা হবে। তবে, এই ব্যবহার বিধি সংজ্ঞার অংশ নয় এবং নির্ভর করা উচিত নয়।