bbgo_origin/pkg/livenote/livenote.go

140 lines
2.2 KiB
Go

package livenote
import (
"sync"
"time"
)
type Object interface {
ObjectID() string
}
type LiveNote struct {
// MessageID is the unique identifier of the message
// for slack, it's the timestamp of the message
MessageID string `json:"messageId"`
ChannelID string `json:"channelId"`
Pin bool `json:"pin"`
TimeToLive time.Duration `json:"timeToLive"`
Object Object
cachedObjID string
postedTime time.Time
}
func NewLiveNote(object Object) *LiveNote {
return &LiveNote{
Object: object,
}
}
func (n *LiveNote) ObjectID() string {
if n.cachedObjID != "" {
return n.cachedObjID
}
n.cachedObjID = n.Object.ObjectID()
return n.cachedObjID
}
func (n *LiveNote) SetTimeToLive(du time.Duration) {
n.TimeToLive = du
}
func (n *LiveNote) SetPostedTime(tt time.Time) {
n.postedTime = tt
}
func (n *LiveNote) SetObject(object Object) {
n.Object = object
}
func (n *LiveNote) SetMessageID(messageID string) {
n.MessageID = messageID
}
func (n *LiveNote) SetChannelID(channelID string) {
n.ChannelID = channelID
}
func (n *LiveNote) SetPin(enabled bool) {
n.Pin = enabled
}
func (n *LiveNote) IsExpired(now time.Time) bool {
if n.postedTime.IsZero() || n.TimeToLive == 0 {
return false
}
expiryTime := n.postedTime.Add(n.TimeToLive)
return now.After(expiryTime)
}
type Pool struct {
notes map[string]*LiveNote
mu sync.Mutex
}
func NewPool(size int64) *Pool {
return &Pool{
notes: make(map[string]*LiveNote, size),
}
}
func (p *Pool) Get(obj Object) *LiveNote {
objID := obj.ObjectID()
p.mu.Lock()
defer p.mu.Unlock()
for _, note := range p.notes {
if note.ObjectID() == objID {
if note.IsExpired(time.Now()) {
return nil
}
return note
}
}
return nil
}
func (p *Pool) Update(obj Object) *LiveNote {
objID := obj.ObjectID()
p.mu.Lock()
defer p.mu.Unlock()
for _, note := range p.notes {
if note.ObjectID() == objID {
if note.IsExpired(time.Now()) {
break
}
// update the object inside the note
note.SetObject(obj)
return note
}
}
note := NewLiveNote(obj)
p.add(objID, note)
return note
}
func (p *Pool) add(id string, note *LiveNote) {
p.notes[id] = note
}
func (p *Pool) Add(note *LiveNote) {
p.mu.Lock()
p.add(note.ObjectID(), note)
p.mu.Unlock()
}