Dopsal jsem 1. verzi své multicache. Asi nejvýznamnějším rozšířením je její integrace na externí zdroje.
Cache můžete plnit skrze resources, což jsou jednoduché funkce pro získávání dat z jakéhokoliv datově zajímavého vstupu. Implementace je postaná na closurech s myšlenkou oddělit logiku samotné cache od procesu získávání dat.
Volání funkcionality pro loadování dat je zabaleno do gorutiny a korektnost synchronizace je pak zajištěna mutexem.
Na Go je pěkné, jak jde všechno jednoduše napsat. Go je blízko C, takže kód je stručný a jasný. Vedle toho closures, GC a ostatní fíčury z něj dělají opravdy efektivní jazyk pro psaní bezpečných, performance náročných aplikací.
Zdroják je volně dostupný na GitHubu pod GPL licencí.
package main import ( "caching/cache" "caching/resources" "fmt" "log" _ "github.com/lib/pq" ) // configs for external resources, should be replaced // in productin by deploy mechanism (reading from env, etc...) var ro = resources.RedisOptions{Addr: "localhost:6379"} var po = resources.PostgreOptions{ Host: "localhost", User: "", Password: "", Db: "", Query: "SELECT key, value FROM cities", } var citiesFile = "./data/cities.json" type cacheConfig struct { name string loader func() (cache.KeyValueStore, error) ttl int64 } var cfg = [...]cacheConfig{{ name: "cities", loader: resources.JSONFile(citiesFile), ttl: 2000, }, { name: "states", loader: resources.Static(), ttl: 2000, }, { name: "fruits", loader: resources.Redis(ro), ttl: 2000, }, { name: "flight", loader: resources.Postgresql(po), ttl: 2000, }} func main() { c := make(cache.Cache) fmt.Println("LOADING DATA 2 CACHE") for _, cc := range cfg { num, err := c.Create(cc.name, cc.loader, cc.ttl) if err != nil { log.Fatal(err) } fmt.Printf("cache %s: loaded %d items\n", cc.name, num) } fmt.Printf("\nREADING FROM CACHES\n") // look for a key in specific cache cName := "states" key := "CZ" if val, ok := c.Get(cName, key); ok { fmt.Printf("[%s] %s => \"%s\"\n", cName, key, val) } // look for a key across all caches key = "CZ" pepa := c.FindAll(key) if len(pepa) > 0 { for i, v := range pepa { fmt.Printf("[%s] %s => \"%s\"\n", i, key, v) } } }