diff --git a/.github/workflows/on-pull-request.yaml b/.github/workflows/on-pull-request.yaml new file mode 100644 index 0000000..756c893 --- /dev/null +++ b/.github/workflows/on-pull-request.yaml @@ -0,0 +1,46 @@ +name: CI + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + +jobs: + on-pull-request: + name: test + strategy: + matrix: + go-version: + - 1.18.x + - 1.19.x + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + + - run: go env + + - name: Cache deps + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install deps + run: go mod download + + - name: Test + run: go test ./... \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1f2b28d..0a2435f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *~ .idea/ +.DS_Store diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5804a55..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: go -go_import_path: github.com/mailgun/groupcache - -os: linux -dist: xenial -sudo: false - -script: - - go test ./... - -go: - - 1.13.x - - 1.14.x - - 1.15.x - - 1.17.x - - master - -cache: - directories: - - $GOPATH/pkg diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 0000000..bbaf26c --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/mailgun/groupcache/v2" +) + +var store = map[string]string{} + +var group = groupcache.NewGroup("cache1", 64<<20, groupcache.GetterFunc( + func(ctx context.Context, key string, dest groupcache.Sink) error { + fmt.Printf("Get Called\n") + v, ok := store[key] + if !ok { + return fmt.Errorf("key not set") + } else { + if err := dest.SetBytes([]byte(v), time.Now().Add(10*time.Minute)); err != nil { + log.Printf("Failed to set cache value for key '%s' - %v\n", key, err) + return err + } + } + + return nil + }, +)) + +func main() { + addr := flag.String("addr", ":8080", "server address") + addr2 := flag.String("api-addr", ":8081", "api server address") + peers := flag.String("pool", "http://localhost:8080", "server pool list") + flag.Parse() + + p := strings.Split(*peers, ",") + pool := groupcache.NewHTTPPoolOpts(fmt.Sprintf("http://%s", *addr), &groupcache.HTTPPoolOptions{}) + pool.Set(p...) + + http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + key := r.FormValue("key") + value := r.FormValue("value") + fmt.Printf("Set: [%s]%s\n", key, value) + store[key] = value + }) + + http.HandleFunc("/cache", func(w http.ResponseWriter, r *http.Request) { + key := r.FormValue("key") + + fmt.Printf("Fetching value for key '%s'\n", key) + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + var b []byte + err := group.Get(ctx, key, groupcache.AllocatingByteSliceSink(&b)) + if err != nil { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + w.Write(b) + w.Write([]byte{'\n'}) + }) + + server := http.Server{ + Addr: *addr, + Handler: pool, + } + + go func() { + if err := server.ListenAndServe(); err != nil { + log.Fatalf("Failed to start HTTP server - %v", err) + } + }() + + go func() { + if err := http.ListenAndServe(*addr2, nil); err != nil { + log.Fatalf("Failed to start API HTTP server - %v", err) + } + }() + + fmt.Printf("Running...\n") + termChan := make(chan os.Signal, 1) + signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM) + <-termChan +}