Skip to content

Instantly share code, notes, and snippets.

@julianfrank
Created November 2, 2016 16:50
Show Gist options
  • Save julianfrank/f6fd4c99833defe02bc943c06ca4595a to your computer and use it in GitHub Desktop.
Save julianfrank/f6fd4c99833defe02bc943c06ca4595a to your computer and use it in GitHub Desktop.
golang simple local cache code
package main
import (
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"
pb "sid"
hi "github.com/julianfrank/gohostinfo"
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
var (
localMap map[string]string // Initialize local key store
)
func apiRouter(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
{
pathLen := len(r.URL.Path)
pathArray := strings.Split(r.URL.Path, "/")
switch pathLen {
case 1: // Root path
{
io.WriteString(w, "Cache Service | Unhandled Method => Method:"+r.Method+" Path:"+r.URL.Path+" Query:"+r.URL.RawQuery)
io.WriteString(w, "\n Current Map\n")
for k, v := range localMap {
io.WriteString(w, "\n"+k+"\t: "+v)
}
}
default:
{
switch strings.ToLower(pathArray[1]) { //pathArray[0] is always"" as it comes before the first /
case "add":
{
queryLen := len(r.URL.RawQuery)
if queryLen > 3 { // 3 Chars minimum required for key value pair
queryArray := strings.Split(r.URL.RawQuery, "&") //Assuming & will be used to separate the query strings
for _, v := range queryArray {
if strings.Contains(v, "=") { //Assuming = will be used to separate the key and values
x := strings.ToLower(strings.Split(v, "=")[0])
y := strings.Split(v, "=")[1]
localMap[x] = y
} else {
localMap[v] = "" // HAndle cases where value is not provided
}
}
io.WriteString(w, "{addstatus:true}") //[TODO]Make it return a proper json string
} else {
io.WriteString(w, "{addstatus:false}") //[TODO]Make it return a proper json string
}
}
case "check":
{
i, ok := localMap[strings.ToLower(r.URL.RawQuery)]
if ok {
io.WriteString(w, "{checkresponse:"+i+"}")
} else {
io.WriteString(w, "{checkresponse:err}")
}
}
case "delete":
{
_, ok := localMap[strings.ToLower(r.URL.RawQuery)]
if ok {
delete(localMap, strings.ToLower(r.URL.RawQuery))
io.WriteString(w, "{deletestatus:true}")
} else {
io.WriteString(w, "{deletestatus:false}")
}
}
case "info":
{
io.WriteString(w, "<!DOCTYPE html><title>CACHE</title><html>")
io.WriteString(w, "<br>Request : <pre>"+hi.RequestInfo(r)+"</pre>")
io.WriteString(w, "<br>Host : <pre>"+hi.HostInfo()+"</pre></html>")
io.WriteString(w, "<br>Service Status : <pre>"+hi.CheckServices("lb", "wfe", "cache", "groupcache", "auth")+"</pre></html>")
}
default:
{
io.WriteString(w, "Cache Service | Unhandled Request => Method:"+r.Method+" Path:"+r.URL.Path+" Query:"+r.URL.RawQuery+" pathLen:"+strconv.Itoa(pathLen)+" pathArray"+strings.Join(pathArray[:], ","))
}
}
}
}
}
default:
{
io.WriteString(w, "Cache Service | Unhandled Method => Method:"+r.Method+" Path:"+r.URL.Path+" Query:"+r.URL.RawQuery)
}
}
}
//sidServer = new(pb.SidSvcServer)
type sidServer struct {
cacheMap map[string]map[string]string
}
func (s *sidServer) CreateSid(ctx context.Context, sid *pb.Sid) (*pb.Status, error) {
log.Println("Cache.go | Called CreateSid")
if len(s.cacheMap) < 1 {
s.cacheMap = make(map[string]map[string]string)
}
d := 100 * time.Millisecond
x := make(map[string]string)
//x[""] = ""
s.cacheMap[sid.Sid] = x
select {
case <-time.After(d):
return &pb.Status{
Status: true,
}, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (s *sidServer) CreateSidPkg(ctx context.Context, pkg *pb.SidPackage) (*pb.Status, error) {
log.Println("Cache.go | Called CreateSidPkg")
d := 100 * time.Millisecond
//s.cacheMap[SidPackage.Sid] = make(map[SidPackage.Kv.]string)
select {
case <-time.After(d):
return &pb.Status{
Status: true,
}, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (s *sidServer) UpdateSid(ctx context.Context, pkg *pb.SidPackage) (*pb.Status, error) {
log.Println("Cache.go | Called UpdateSid")
d := 100 * time.Millisecond
//s.cacheMap[SidPackage.Sid] = make(map[SidPackage.Kv.]string)
select {
case <-time.After(d):
return &pb.Status{
Status: true,
}, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (s *sidServer) CheckSid(ctx context.Context, sid *pb.Sid) (*pb.Status, error) {
log.Println("Cache.go | Called CheckSid")
d := 100 * time.Millisecond
//s.cacheMap[SidPackage.Sid] = make(map[SidPackage.Kv.]string)
select {
case <-time.After(d):
return &pb.Status{
Status: true,
}, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (s *sidServer) CheckSidValue(ctx context.Context, sid *pb.Sid) (*pb.SidPackage, error) {
log.Println("Cache.go | Called CheckSidValue")
d := 100 * time.Millisecond
//s.cacheMap[SidPackage.Sid] = make(map[SidPackage.Kv.]string)
select {
case <-time.After(d):
return nil, nil
/*return &pb.Status{
Status: true,
}, nil8*/
case <-ctx.Done():
return nil, ctx.Err()
}
}
func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 777)) // RPC port
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
g := grpc.NewServer()
pb.RegisterSidSvcServer(g, &sidServer{})
g.Serve(lis)
mux := http.NewServeMux() // Application Route Handlers
mux.HandleFunc("/", apiRouter)
serverPort := os.Getenv("PORT")
if len(serverPort) < 2 {
serverPort = "80"
}
log.Println("CACHE Listening on " + serverPort)
s := &http.Server{
Addr: ":" + serverPort,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment