From 8bfbf7658ad57403cd37547c2bcb9f6cc671b096 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Wed, 26 Nov 2025 23:50:55 +0700 Subject: [PATCH] feat: init --- valkey/.env.example | 1 + valkey/.gitignore | 4 +++ valkey/Dockerfile | 40 ++++++++++++++++++++++++ valkey/go.mod | 12 ++++++++ valkey/go.sum | 16 ++++++++++ valkey/main.go | 74 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 147 insertions(+) create mode 100644 valkey/.env.example create mode 100644 valkey/Dockerfile create mode 100644 valkey/go.mod create mode 100644 valkey/go.sum create mode 100644 valkey/main.go diff --git a/valkey/.env.example b/valkey/.env.example new file mode 100644 index 0000000..e0ea526 --- /dev/null +++ b/valkey/.env.example @@ -0,0 +1 @@ +VALKEY_URL=valkey://default@127.0.0.1:6379 diff --git a/valkey/.gitignore b/valkey/.gitignore index aaadf73..089a213 100644 --- a/valkey/.gitignore +++ b/valkey/.gitignore @@ -1,3 +1,7 @@ +.idea + + + # If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # diff --git a/valkey/Dockerfile b/valkey/Dockerfile new file mode 100644 index 0000000..00895c4 --- /dev/null +++ b/valkey/Dockerfile @@ -0,0 +1,40 @@ +ARG GO_VERSION=1.24.10 +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build +WORKDIR /src + +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x + +ARG TARGETARCH + +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,target=. \ + CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /bin/server . + +FROM alpine:latest AS final + +RUN --mount=type=cache,target=/var/cache/apk \ + apk --update add \ + ca-certificates \ + tzdata \ + && \ + update-ca-certificates + +ARG UID=10001 +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + appuser +USER appuser + +COPY --from=build /bin/server /bin/ + +EXPOSE 1999 + +ENTRYPOINT [ "/bin/server" ] diff --git a/valkey/go.mod b/valkey/go.mod new file mode 100644 index 0000000..2093dad --- /dev/null +++ b/valkey/go.mod @@ -0,0 +1,12 @@ +module github.com/tiennm99/valkey-keepalive + +go 1.23.12 + +toolchain go1.24.10 + +require ( + github.com/joho/godotenv v1.5.1 + github.com/valkey-io/valkey-go v1.0.68 +) + +require golang.org/x/sys v0.31.0 // indirect diff --git a/valkey/go.sum b/valkey/go.sum new file mode 100644 index 0000000..1b73a94 --- /dev/null +++ b/valkey/go.sum @@ -0,0 +1,16 @@ +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/valkey-io/valkey-go v1.0.68 h1:bTbfonp49b41DqrF30q+y2JL3gcbjd2IiacFAtO4JBA= +github.com/valkey-io/valkey-go v1.0.68/go.mod h1:bHmwjIEOrGq/ubOJfh5uMRs7Xj6mV3mQ/ZXUbmqpjqY= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/valkey/main.go b/valkey/main.go new file mode 100644 index 0000000..b266a0a --- /dev/null +++ b/valkey/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "log" + "os" + "os/signal" + "syscall" + "time" + + "github.com/joho/godotenv" + "github.com/valkey-io/valkey-go" +) + +func main() { + if err := godotenv.Load(); err != nil { + log.Println("Warning: .env file not found") + } + + valkeyUrl, isExist := os.LookupEnv("VALKEY_URL") + if !isExist { + log.Fatal("Warning: VALKEY_URL not set!") + return + } + + opt, err := valkey.ParseURL(valkeyUrl) + if err != nil { + log.Fatal(err) + } + + client, err := valkey.NewClient(opt) + if err != nil { + log.Fatal(err) + } + + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + ticker := time.NewTicker(time.Minute) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if err := incrementCounter(ctx, client); err != nil { + log.Printf("Keepalive increment error: %v", err) + } + case <-ctx.Done(): + return + } + } + }() + + defer func() { + cancel() + client.Close() + }() + + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + <-sigCh +} + +func incrementCounter(ctx context.Context, client valkey.Client) error { + ctx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + + increment, err := client.Do(ctx, client.B().Incr().Key("counter").Build()).AsInt64() + if err != nil { + return err + } + log.Printf("Counter : %d\n", increment) + return nil +}