Last active
April 30, 2024 09:51
-
-
Save adhocore/6bce87515c045d046583983f8fc51e93 to your computer and use it in GitHub Desktop.
BigCache Server using fasthttp
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
package main | |
import ( | |
"context" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"strconv" | |
"strings" | |
"github.com/adhocore/fasthttp" | |
"github.com/allegro/bigcache/v3" | |
) | |
const ( | |
// server version. | |
version = "1.0.0" | |
) | |
var ( | |
port int | |
logfile string | |
ver bool | |
// cache-specific settings. | |
cache *bigcache.BigCache | |
config = bigcache.Config{} | |
) | |
func init() { | |
flag.BoolVar(&config.Verbose, "v", false, "Verbose logging.") | |
flag.IntVar(&config.Shards, "shards", 1024, "Number of shards for the cache.") | |
flag.IntVar(&config.MaxEntriesInWindow, "maxInWindow", 1000*10*60, "Used only in initial memory allocation.") | |
flag.DurationVar(&config.LifeWindow, "lifetime", 100000*100000*60, "Lifetime of each cache object.") | |
flag.IntVar(&config.HardMaxCacheSize, "max", 8192, "Maximum amount of data in the cache in MB.") | |
flag.IntVar(&config.MaxEntrySize, "maxShardEntrySize", 500, "The maximum size of each object stored in a shard. Used only in initial memory allocation.") | |
flag.IntVar(&port, "port", 9090, "The port to listen on.") | |
flag.StringVar(&logfile, "logfile", "", "Location of the logfile.") | |
flag.BoolVar(&ver, "version", false, "Print server version.") | |
} | |
func main() { | |
flag.Parse() | |
if ver { | |
fmt.Printf("BigCache HTTP Server v%s", version) | |
os.Exit(0) | |
} | |
var logger *log.Logger | |
if logfile == "" { | |
logger = log.New(os.Stdout, "", log.LstdFlags) | |
} else { | |
f, err := os.OpenFile(logfile, os.O_APPEND|os.O_WRONLY, 0600) | |
if err != nil { | |
panic(err) | |
} | |
logger = log.New(f, "", log.LstdFlags) | |
} | |
var err error | |
cache, err = bigcache.New(context.Background(), config) | |
if err != nil { | |
logger.Fatal(err) | |
} | |
logger.Print("cache initialised.") | |
app := fasthttp.New() | |
sub := app.Group("/c") | |
sub.Get("/:key", func(c *fasthttp.Ctx) error { | |
entry, err := cache.Get(c.Params("key")) | |
if err != nil { | |
if strings.Contains(err.Error(), "not found") { | |
return c.SendStatus(fasthttp.StatusNotFound) | |
} else { | |
return c.SendStatus(fasthttp.StatusInternalServerError) | |
} | |
} | |
return c.Send(entry) | |
}) | |
sub.Post("/:key", func(c *fasthttp.Ctx) error { | |
body := c.BodyRaw() | |
entry := make([]byte, len(body)) | |
copy(entry, body) | |
if err := cache.Set(c.Params("key"), entry); err != nil { | |
return c.SendStatus(fasthttp.StatusInternalServerError) | |
} | |
return c.SendStatus(fasthttp.StatusCreated) | |
}) | |
sub.Delete("/:key", func(c *fasthttp.Ctx) error { | |
if err := cache.Delete(c.Params("key")); err != nil { | |
return c.SendStatus(fasthttp.StatusInternalServerError) | |
} | |
return c.SendStatus(fasthttp.StatusOK) | |
}) | |
app.Get("/stats", func(c *fasthttp.Ctx) error { | |
return c.JSON(cache.Stats()) | |
}) | |
logger.Printf("starting server on :%d", port) | |
strPort := ":" + strconv.Itoa(port) | |
log.Fatal("serve: ", app.Serve(strPort)) | |
} | |
// run: | |
// go run bigcache.go | |
// | |
// set cache with key 'xyz' | |
// curl 0:9090/c/xyz -d'{"val":"value"}' | |
// | |
// get cache with key 'xyz' | |
// curl 0:9090/c/xyz | |
// | |
// del cache with key 'xyz' | |
// curl -XDELETE 0:9090/c/xyz | |
// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment