Exemple #1
0
// NewCachedAnnouncementStore returns a cache wrapper around the existing store
func NewCachedAnnouncementStore(store Store, options CacheOptions) Store {
	serviceCache := gcache.New(options.ServiceCacheSize).Expiration(options.ServiceCacheExpiration).LRU().
		LoaderFunc(func(k interface{}) (interface{}, error) {
			key := strings.Split(k.(string), ":")
			return store.Get(key[0], key[1])
		}).Build()

	listCache := gcache.New(options.ListCacheSize).Expiration(options.ListCacheExpiration).LRU().
		LoaderFunc(func(k interface{}) (interface{}, error) {
			key := k.(string)
			announcements, err := store.ListService(key)
			if err != nil {
				return nil, err
			}
			go func(announcements []*Announcement) {
				for _, announcement := range announcements {
					serviceCache.Set(serviceCacheKey(announcement.ServiceName, announcement.ID), announcement)
				}
			}(announcements)
			return announcements, nil
		}).Build()

	return &cachedAnnouncementStore{
		backingStore: store,
		serviceCache: serviceCache,
		listCache:    listCache,
	}
}
Exemple #2
0
func buildLoadingARCache(size int) gcache.Cache {
	return gcache.New(size).
		ARC().
		LoaderFunc(loader).
		EvictedFunc(evictedFuncForARC).
		Build()
}
Exemple #3
0
func buildLoadingSimpleCache(size int, loader gcache.LoaderFunc) gcache.Cache {
	return gcache.New(size).
		LoaderFunc(loader).
		Simple().
		EvictedFunc(evictedFuncForSimple).
		Build()
}
Exemple #4
0
// NewClient returns a new Client
func NewClient(server string, announcement *Announcement, tokenFunc func() string) (Client, error) {
	conn, err := api.Dial(server)
	if err != nil {
		return nil, err
	}
	client := &DefaultClient{
		lists:        make(map[string][]*Announcement),
		listsUpdated: make(map[string]time.Time),
		self:         announcement,
		tokenFunc:    tokenFunc,
		conn:         conn,
		client:       NewDiscoveryClient(conn),
	}
	client.cache = gcache.
		New(CacheSize).
		Expiration(CacheExpiration).
		LRU().
		LoaderFunc(func(k interface{}) (interface{}, error) {
			key, ok := k.(cacheKey)
			if !ok {
				return nil, fmt.Errorf("wrong type for cacheKey: %T", k)
			}
			return client.get(key.serviceName, key.id)
		}).
		Build()
	return client, nil
}
Exemple #5
0
func buildLRUCache(size int) gcache.Cache {
	return gcache.New(size).
		LRU().
		EvictedFunc(evictedFuncForLRU).
		Expiration(time.Second).
		Build()
}
Exemple #6
0
func main() {
	defer mustbe.Catched(func(err error) { log.Fatalln("Fatal error:", err) })

	var (
		botToken   string
		apiHost    string
		dbFileName string
	)

	flag.StringVar(&botToken, "token", "", "telegram bot token")
	flag.StringVar(&apiHost, "apihost", "freefeed.net", "backend API host")
	flag.StringVar(&dbFileName, "dbfile", "", "database file name")
	flag.Parse()

	if botToken == "" || dbFileName == "" {
		flag.Usage()
		return
	}

	db := mustbe.OKVal(bolt.Open(dbFileName, 0600, &bolt.Options{Timeout: 1 * time.Second})).(*bolt.DB)
	defer db.Close()

	mustbe.OK(db.Update(func(tx *bolt.Tx) error {
		mustbe.OKVal(tx.CreateBucketIfNotExists(StatesBucket))
		return nil
	}))

	bot := mustbe.OKVal(tgbotapi.NewBotAPI(botToken)).(*tgbotapi.BotAPI)

	u := tgbotapi.NewUpdate(0)
	u.Timeout = 60

	updates, err := bot.GetUpdatesChan(u)
	if err != nil {
		log.Fatalln("Can not get update chan:", err)
		return
	}

	log.Println("Starting bot", bot.Self.UserName)

	app := &App{
		db:      db,
		apiHost: apiHost,
		outbox:  make(chan tgbotapi.Chattable, 0),
		rts:     make(map[int]*Realtime),
		cache:   gcache.New(1000).ARC().Build(),
	}

	app.LoadRT()

	for {
		select {
		case update := <-updates:
			go app.HandleMessage(&update.Message)
		case msg := <-app.outbox:
			bot.Send(msg)
		}
	}
}
Exemple #7
0
func buildLoadingLRUCache(size int, loader gcache.LoaderFunc) gcache.Cache {
	return gcache.New(size).
		LRU().
		LoaderFunc(loader).
		EvictedFunc(evictedFuncForLRU).
		Expiration(time.Second).
		Build()
}
Exemple #8
0
// newReverseResolver starts a new reverse resolver that performs reverse
// resolutions and caches the result.
func newReverseResolver() *reverseResolver {
	r := reverseResolver{
		addresses: make(chan string, rAddrBacklog),
		cache:     gcache.New(rAddrCacheLen).LRU().Expiration(rAddrCacheExpiration).Build(),
		Throttle:  time.Tick(time.Second / 10),
		Resolver:  net.LookupAddr,
	}
	go r.loop()
	return &r
}
Exemple #9
0
func main() {
	gc := gcache.New(10).
		LFU().
		Build()
	gc.Set("key", "ok")

	v, err := gc.Get("key")
	if err != nil {
		panic(err)
	}
	fmt.Println("value:", v)
}
Exemple #10
0
func main() {
	gc := gcache.New(10).
		LFU().
		LoaderFunc(func(key interface{}) (interface{}, error) {
			return fmt.Sprintf("%v-value", key), nil
		}).
		Build()

	v, err := gc.Get("key")
	if err != nil {
		panic(err)
	}
	fmt.Println(v)
}
Exemple #11
0
func buildARCache(size int) gcache.Cache {
	return gcache.New(size).
		ARC().
		EvictedFunc(evictedFuncForARC).
		Build()
}
Exemple #12
0
package render

import (
	"fmt"
	"math/rand"

	"github.com/bluele/gcache"

	"$GITHUB_URI/report"
)

var renderCache = gcache.New(100).LRU().Build()

type memoise struct {
	Renderer
	id string
}

// Memoise wraps the renderer in a loving embrace of caching
func Memoise(r Renderer) Renderer {
	return &memoise{
		Renderer: r,
		id:       fmt.Sprintf("%x", rand.Int63()),
	}
}

// Render produces a set of Nodes given a Report.
// Ideally, it just retrieves it from the cache, otherwise it calls through to
// `r` and stores the result.
func (m *memoise) Render(rpt report.Report, dct Decorator) report.Nodes {
	key := fmt.Sprintf("%s-%s", rpt.ID, m.id)
Exemple #13
0
// Delimiters are used to separate parts of node IDs, to guarantee uniqueness
// in particular contexts.
const (
	// ScopeDelim is a general-purpose delimiter used within node IDs to
	// separate different contextual scopes. Different topologies have
	// different key structures.
	ScopeDelim = ";"

	// EdgeDelim separates two node IDs when they need to exist in the same key.
	// Concretely, it separates node IDs in keys that represent edges.
	EdgeDelim = "|"
)

var (
	idCache = gcache.New(1024).LRU().Build()
	hashers = sync.Pool{
		New: func() interface{} {
			return fnv.New64a()
		},
	}
)

func lookupID(part1, part2, part3 string, f func() string) string {
	h := hashers.Get().(hash.Hash64)
	h.Write([]byte(part1))
	h.Write([]byte(part2))
	h.Write([]byte(part3))
	sum := h.Sum64()
	var result string
	if id, err := idCache.Get(sum); id != nil && err != nil {
func NewCache(s int) CacheMiddleware {
	c := new(inMemoryCacheMiddleware)
	c.cache = gcache.New(s).LRU().Build()
	return c
}
Exemple #15
0
func buildSimpleCache(size int) gcache.Cache {
	return gcache.New(size).
		Simple().
		EvictedFunc(evictedFuncForSimple).
		Build()
}
Exemple #16
0
package main

import (
	"fmt"
	"strconv"
	"time"

	"github.com/bluele/gcache"
)

const cacheSize = 500

// On every connect and accept, we lookup the local addr
// As this is expensive, we cache the result
var fdAddrCache = gcache.New(cacheSize).LRU().Expiration(15 * time.Second).Build()

type fdCacheKey struct {
	pid int
	fd  int
}
type fdCacheValue struct {
	addr uint32
	port uint16
}

func getCachedLocalAddr(pid, fd int) (uint32, uint16, error) {
	key := fdCacheKey{pid, fd}
	val, err := fdAddrCache.Get(key)
	if val != nil {
		return val.(fdCacheValue).addr, val.(fdCacheValue).port, nil
	}