Tunny, senkron API'ları kullanarak herhangi bir sayıda gorutinden işi sınırlamanıza izin veren ve gorutin havuzları oluşturup yönetmenizi sağlayan bir Golang kütüphanesidir.
İşiniz herhangi bir sayıda asenkron kaynaktan geliyorsa, ancak paralel işleme kapasiteniz sınırlıysa, sabit bir gorutin havuzu son derece kullanışlıdır. Örneğin, CPU yoğunluğunda HTTP istek işlemleri sırasında, CPU sayısına göre bir havuz oluşturabilirsiniz.
## Yükleme
```shell
go get github.com/Jeffail/tunny
Alternatif olarak, dep kullanarak:
dep ensure -add github.com/Jeffail/tunny
Kullanım
Çoğu durumda, ağır işiniz basit bir func()
ile temsil edilebilir, bu durumda NewFunc
kullanabilirsiniz. HTTP isteklerinden CPU sayısını hesaplama örneğimizi nasıl kullanacağımıza bakalım:
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 ile bazı CPU-yoğun işlemleri gerçekleştirin
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, "İç hata", http.StatusInternalServerError)
}
defer r.Body.Close()
// Bu işi havuzumuza dahil edin. Bu çağrı senkron ve iş tamamlanana kadar bloklanacaktır.
result := pool.Process(input)
w.Write(result.([]byte))
})
http.ListenAndServe(":8080", nil)
}
Tunny, zaman aşımını da destekler. Yukarıdaki Process
çağrısını aşağıdaki kod ile değiştirebilirsiniz:
result, err := pool.ProcessTimed(input, time.Second*5)
if err == tunny.ErrJobTimedOut {
http.Error(w, "İstek zaman aşımına uğradı", http.StatusRequestTimeout)
}
Ayrıca istek bağlamını (veya herhangi bir bağlamı) zaman aşımını ve son tarihleri işlemek için de kullanabilirsiniz. Sadece Process
çağrısını aşağıdaki kod ile değiştirin:
result, err := pool.ProcessCtx(r.Context(), input)
if err == context.DeadlineExceeded {
http.Error(w, "İstek zaman aşımına uğradı", http.StatusRequestTimeout)
}
Havuz Boyutunu Değiştirme
SetSize(int)
kullanarak Tunny havuzunun boyutunu istediğiniz zaman değiştirebilirsiniz.
pool.SetSize(10) // 10 gorutin
pool.SetSize(100) // 100 gorutin
Bu, diğer gorutinler hala işlem yapıyorken bile güvenlidir.
Durumlu Gorutin
Bazen, Tunny havuzundaki her gorutin kendi yönetim durumuna ihtiyaç duyar. Bu durumda, tunny.Worker
'i uygulamanız gerekecektir, bu durum kapatma, kesmeyi (eğer bir iş zaman aşımına uğrarsa ve artık gerekli değilse) ve belirli bir koşul karşılanana kadar bir sonraki işin tahsisini engelleme çağrılarını içerir.
Worker
türü ile havuz oluştururken, özel uygulamanızı oluşturmak için bir kurucu sağlamanız gerekir:
pool := tunny.New(poolSize, func() Worker {
// TODO: Her gorutin için durum tahsisi yapın.
return newCustomWorker()
})
Bu şekilde, Tunny havuz boyutu değiştiğinde Worker
türünün yaratılıp yok edilmesini temizleyebilir.
Sıralama
Bekleyen işlerin sırayla işlenmesi garanti edilmez. Mevcut kanalların ve seçim bloklarının uygulaması nedeniyle, bekleyen iş yığınları FIFO kuyruğu olarak işlenir. Ancak, bu davranış özellik değildir ve buna güvenilmemelidir.