mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-10-08 20:07:51 +00:00
93 lines
1.7 KiB
Go
93 lines
1.7 KiB
Go
package hold
|
|
|
|
import (
|
|
"errors"
|
|
log "github.com/cihub/seelog"
|
|
. "pilosa/util"
|
|
"time"
|
|
)
|
|
|
|
type holdchan chan interface{}
|
|
type gethold struct {
|
|
id *GUID
|
|
reply chan holdchan
|
|
}
|
|
type delhold struct {
|
|
id *GUID
|
|
}
|
|
|
|
type Holder struct {
|
|
data map[GUID]holdchan
|
|
getchan chan gethold
|
|
delchan chan delhold
|
|
}
|
|
|
|
//var Hold Holder
|
|
|
|
func (self *Holder) DelChan(id *GUID) {
|
|
log.Trace("Holder.DelChan", id)
|
|
req := delhold{id}
|
|
self.delchan <- req
|
|
}
|
|
|
|
func (self *Holder) GetChan(id *GUID) holdchan {
|
|
log.Trace("Holder.GetChan", id)
|
|
reply := make(chan holdchan)
|
|
req := gethold{id, reply}
|
|
self.getchan <- req
|
|
return <-reply
|
|
}
|
|
|
|
func (self *Holder) Get(id *GUID, timeout int) (interface{}, error) {
|
|
log.Trace("Holder.Get", id, timeout)
|
|
ch := self.GetChan(id)
|
|
select {
|
|
case val := <-ch:
|
|
return val, nil
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
self.DelChan(id)
|
|
return nil, errors.New("Timeout getting from holder")
|
|
}
|
|
}
|
|
|
|
func (self *Holder) Set(id *GUID, value interface{}, timeout int) {
|
|
log.Trace("Holder.Set", id, value, timeout)
|
|
ch := self.GetChan(id)
|
|
go func() {
|
|
select {
|
|
case ch <- value:
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
}
|
|
self.DelChan(id)
|
|
}()
|
|
}
|
|
|
|
func (self *Holder) Run() {
|
|
var greq gethold
|
|
var dreq delhold
|
|
for {
|
|
select {
|
|
case greq = <-self.getchan:
|
|
item, ok := self.data[*greq.id]
|
|
if !ok {
|
|
item = make(holdchan)
|
|
self.data[*greq.id] = item
|
|
}
|
|
greq.reply <- item
|
|
case dreq = <-self.delchan:
|
|
delete(self.data, *dreq.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
func NewHolder() *Holder {
|
|
h := Holder{make(map[GUID]holdchan), make(chan gethold), make(chan delhold)}
|
|
return &h
|
|
}
|
|
|
|
/*
|
|
func init() {
|
|
Hold = Holder{make(map[GUID]holdchan), make(chan gethold), make(chan delhold)}
|
|
go Hold.Run()
|
|
}
|
|
*/
|