-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
jc3wish
authored and
jc3wish
committed
Oct 21, 2019
1 parent
3deb3d2
commit 67ea3f0
Showing
6 changed files
with
230 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package xdb | ||
|
||
import ( | ||
"sync" | ||
"time" | ||
"fmt" | ||
"runtime/debug" | ||
"log" | ||
) | ||
|
||
type PoolClient struct { | ||
sync.RWMutex | ||
ClientChan chan *Client | ||
Uri string | ||
MaxClientCount uint8 | ||
CurrentClientCount uint8 | ||
AvailableCount uint8 | ||
} | ||
|
||
var clientPool map[string]*PoolClient | ||
|
||
func init() { | ||
clientPool = make(map[string]*PoolClient,0) | ||
} | ||
|
||
func InitClientPool(name string,uri string,count uint8) error{ | ||
if _,ok:=clientPool[name];!ok{ | ||
clientPool[name] = &PoolClient{ | ||
ClientChan: make(chan *Client, int(count)), | ||
Uri:uri, | ||
MaxClientCount: count, | ||
CurrentClientCount: 0, | ||
AvailableCount:0, | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func GetClient(name string) (c *Client,err error) { | ||
if _,ok:=clientPool[name];!ok{ | ||
return nil,fmt.Errorf(name+" not esxit") | ||
} | ||
t := clientPool[name] | ||
t.Lock() | ||
if t.AvailableCount > 0 { | ||
t.AvailableCount-- | ||
t.Unlock() | ||
//这里为什么不需要timeout,是因为前面加了lock 判断空闲连接数 | ||
c = <- t.ClientChan | ||
return | ||
} | ||
if t.MaxClientCount > t.CurrentClientCount{ | ||
t.CurrentClientCount++ | ||
t.Unlock() | ||
f,stringKey := NewClient(name,t.Uri) | ||
if f == nil{ | ||
t.Lock() | ||
t.CurrentClientCount-- | ||
t.Unlock() | ||
} | ||
return f,stringKey | ||
} | ||
t.Unlock() | ||
timer := time.NewTimer(5 * time.Second) | ||
select { | ||
case c = <-t.ClientChan: | ||
break | ||
case <- timer.C: | ||
break | ||
} | ||
timer.Stop() | ||
if c == nil{ | ||
return nil,fmt.Errorf("get client time out") | ||
} | ||
t.Lock() | ||
t.AvailableCount-- | ||
t.Unlock() | ||
return | ||
} | ||
|
||
func BackCient(name string,c *Client) bool { | ||
defer func() { | ||
if err := recover();err !=nil{ | ||
log.Println(string(debug.Stack())) | ||
return | ||
} | ||
}() | ||
if _,ok:=clientPool[name];!ok{ | ||
return true | ||
} | ||
t:=clientPool[name] | ||
t.Lock() | ||
if t.CurrentClientCount > t.MaxClientCount{ | ||
t.CurrentClientCount-- | ||
func(){ | ||
defer func() { | ||
if err := recover();err != nil{ | ||
log.Println(string(debug.Stack())) | ||
return | ||
} | ||
}() | ||
//调用插件函数,关闭连接,这里防止插件代码写得有问题,抛异常,所以这里需要recover一次 | ||
c.Close() | ||
}() | ||
}else{ | ||
t.AvailableCount++ | ||
t.ClientChan <- c | ||
} | ||
t.Unlock() | ||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package xdb_test | ||
|
||
import ( | ||
"github.com/brokercap/Bifrost/xdb" | ||
"testing" | ||
) | ||
|
||
func setKeyVal(table,key1 string,value interface{}) error { | ||
client,err := xdb.GetClient("leveldb") | ||
if err != nil{ | ||
return err | ||
} | ||
defer xdb.BackCient("leveldb",client) | ||
client.SetPrefix("xdbtest").PutKeyVal(table,key1,value) | ||
return nil | ||
} | ||
|
||
func getKeyVal(table,key1 string) ([]byte,error) { | ||
client,err := xdb.GetClient("leveldb") | ||
if err != nil{ | ||
return nil,err | ||
} | ||
defer xdb.BackCient("leveldb",client) | ||
c,err := client.GetKeyValBytes(table,key1) | ||
return c,err | ||
} | ||
|
||
func TestPool(t *testing.T) { | ||
xdb.InitClientPool("leveldb","./myleveldir4",1) | ||
|
||
type DataSource struct { | ||
Name string | ||
Uri string | ||
} | ||
|
||
var table,key1,key2 string | ||
var val1,val2 DataSource | ||
|
||
table = "data_source" | ||
|
||
key1 = "tstst1" | ||
val1 = DataSource{Name:"sss",Uri:"URI1"} | ||
err0 := setKeyVal(table,key1,val1) | ||
if err0 != nil{ | ||
t.Fatal(key1, " put error:",err0) | ||
}else{ | ||
t.Log(key1," put success") | ||
} | ||
|
||
key2 = "tstst2" | ||
val2 = DataSource{Name:"sss22",Uri:"URI1222"} | ||
err0 = setKeyVal(table,key2,val2) | ||
|
||
if err0 != nil{ | ||
t.Fatal(key2, " put error:",err0) | ||
}else{ | ||
t.Log(key2," put success") | ||
} | ||
|
||
c,err1 := getKeyVal(table,key1) | ||
t.Log(key1," c:",string(c),"err1:",err1) | ||
|
||
|
||
c,err1 = getKeyVal(table,key2) | ||
t.Log(key2," c:",string(c),"err1:",err1) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters