分析一個簡單的goroutine資源池 tunny。
從資源池中獲取goroutine並進行處理的邏輯如下:
tunny將goroutine處理單元封裝為workWrapper
,由此可以對goroutine的數目進行限制。
workerWrapper.run()作為一個goroutine,內部負責具體事務的處理。其會將一個workRequest
(可以看作是請求處理單元)放入reqChan
,並阻塞等待使用方的呼叫。workRequest
主要包含兩個channel,其中jobChan
用於傳入呼叫方的輸入,retChan
用於給呼叫方返回執行結果。
呼叫方會從pool的reqChan中獲取一個workRequest
請求處理單元,並在workRequest.jobChan
中傳參,這樣workerWrapper.run()中就會繼續進行work.process
處理。處理結束之後將結果通過workRequest.retChan
返回給呼叫方,然後繼續通過reqChan <- workRequest
阻塞等待下一個呼叫方的處理。
其中workerWrapper.run()中的work
是一個需要使用者實現的介面,介面內容如下,最重要的介面是Process(interface{}) interface{}
type Worker interface {
// Process will synchronously perform a job and return the result.
Process(interface{}) interface{}
// BlockUntilReady is called before each job is processed and must block the
// calling goroutine until the Worker is ready to process the next job.
BlockUntilReady()
// Interrupt is called when a job is cancelled. The worker is responsible
// for unblocking the Process implementation.
Interrupt()
// Terminate is called when a Worker is removed from the processing pool
// and is responsible for cleaning up any held resources.
Terminate()
}
結論
tunny中的封裝和處理函式並不適合所有的場景,但可以借鑑其核心思想來構造特定場景下的goroutine資源池。