searcher pool is ready
This commit is contained in:
parent
ab22a5e03c
commit
e73321a860
|
|
@ -11,9 +11,9 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
)
|
||||
|
|
@ -61,18 +61,19 @@ func NewSearcherPool(config *Config) (*SearcherPool, error) {
|
|||
// Stat return the stat {loanCount, leftCount} info of the pool
|
||||
func (sp *SearcherPool) Stat() (int, int) {
|
||||
loanCount := int(atomic.LoadInt32(&sp.loanCount))
|
||||
return loanCount, len(sp.pool) - loanCount
|
||||
return loanCount, len(sp.pool)
|
||||
}
|
||||
|
||||
// get the loaned count
|
||||
func (sp *SearcherPool) LoanCount() int {
|
||||
return int(atomic.LoadInt32(&sp.loanCount))
|
||||
}
|
||||
|
||||
func (sp *SearcherPool) BorrowSearcher() *xdb.Searcher {
|
||||
select {
|
||||
case <-sp.closing:
|
||||
// stop searcher borrow while closing
|
||||
return nil
|
||||
case s := <-sp.pool:
|
||||
// @Note: still accept searcher borrow while closing
|
||||
s := <-sp.pool
|
||||
atomic.AddInt32(&sp.loanCount, 1)
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
func (sp *SearcherPool) ReturnSearcher(searcher *xdb.Searcher) {
|
||||
|
|
@ -80,6 +81,9 @@ func (sp *SearcherPool) ReturnSearcher(searcher *xdb.Searcher) {
|
|||
case <-sp.closing:
|
||||
// manually close the searcher
|
||||
searcher.Close()
|
||||
|
||||
// decrease the loan count
|
||||
atomic.AddInt32(&sp.loanCount, -1)
|
||||
default:
|
||||
// return the searcher
|
||||
sp.pool <- searcher
|
||||
|
|
@ -87,9 +91,29 @@ func (sp *SearcherPool) ReturnSearcher(searcher *xdb.Searcher) {
|
|||
}
|
||||
}
|
||||
|
||||
func (sp *SearcherPool) Close(ctx context.Context) {
|
||||
func (sp *SearcherPool) Close() {
|
||||
sp.CloseTimeout(time.Second * 10)
|
||||
}
|
||||
|
||||
func (sp *SearcherPool) CloseTimeout(d time.Duration) {
|
||||
close(sp.closing)
|
||||
for s := range sp.pool {
|
||||
for {
|
||||
timeout := false
|
||||
select {
|
||||
case s := <-sp.pool:
|
||||
s.Close()
|
||||
case <-time.After(d):
|
||||
// check if all the loaned searchers was closed
|
||||
timeout = true
|
||||
}
|
||||
|
||||
lc, left := sp.LoanCount(), len(sp.pool)
|
||||
if left == 0 && lc == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if timeout {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
||||
// Use of this source code is governed by a Apache2.0-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestV4SearcherPool(t *testing.T) {
|
||||
v4Config, err := NewV4Config(VIndexCache, "../../../data/ip2region_v4.xdb", 5)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to new v4 config: %s", err)
|
||||
}
|
||||
|
||||
searcherPool, err := NewSearcherPool(v4Config)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create searcher pool: %s", err)
|
||||
}
|
||||
|
||||
ipString := "219.133.110.197"
|
||||
for i := 0; i < 20; i++ {
|
||||
searcher := searcherPool.BorrowSearcher()
|
||||
region, err := searcher.SearchByStr(ipString)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to search(%s): %s", ipString, err)
|
||||
}
|
||||
|
||||
fmt.Printf("%2d->search(%s)=%s\n", i, ipString, region)
|
||||
searcherPool.ReturnSearcher(searcher)
|
||||
}
|
||||
|
||||
// borrow one at last for Close timeout wait testing ONLY
|
||||
// searcherPool.BorrowSearcher()
|
||||
|
||||
// close the searcher pool
|
||||
searcherPool.Close()
|
||||
}
|
||||
|
||||
func TestV6SearcherPool(t *testing.T) {
|
||||
v6Config, err := NewV6Config(VIndexCache, "../../../data/ip2region_v6.xdb", 5)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to new v6 config: %s", err)
|
||||
}
|
||||
|
||||
searcherPool, err := NewSearcherPool(v6Config)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create searcher pool: %s", err)
|
||||
}
|
||||
|
||||
ipString := "240e:3b7:3275:f090:d2a3:7d1a:dd90:c3b6"
|
||||
for i := 0; i < 20; i++ {
|
||||
searcher := searcherPool.BorrowSearcher()
|
||||
region, err := searcher.SearchByStr(ipString)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to search(%s): %s", ipString, err)
|
||||
}
|
||||
|
||||
fmt.Printf("%2d->search(%s)=%s\n", i, ipString, region)
|
||||
searcherPool.ReturnSearcher(searcher)
|
||||
}
|
||||
|
||||
// borrow one at last for Close timeout wait testing ONLY
|
||||
// searcherPool.BorrowSearcher()
|
||||
|
||||
// close the searcher pool
|
||||
searcherPool.Close()
|
||||
}
|
||||
Loading…
Reference in New Issue