From 923f07c79d59f6a84130ae95c3b5b57b92e9a0ce Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Tue, 16 Apr 2024 22:56:14 +0900 Subject: [PATCH 01/19] Revert "Revert "feat(server): style in-memory cache support" (#960)" This reverts commit 14aead9ee614886eac7f0dde6a41678a4643b97e. --- .gitignore | 1 + docker-compose.yml | 8 +- go.work.sum | 4 +- server/.env.example | 8 ++ server/Makefile | 5 +- server/e2e/common.go | 17 +++ server/e2e/gql_style_test.go | 31 ++++- server/e2e/ping_test.go | 8 ++ server/go.mod | 42 +++++-- server/go.sum | 119 ++++++++++++------ .../adapter/gql/resolver_mutation_style.go | 5 + server/internal/app/app.go | 2 +- server/internal/app/config/config.go | 8 ++ server/internal/app/main.go | 29 +++++ server/internal/app/usecase.go | 5 +- .../infrastructure/redis/redis_adapter.go | 23 ++++ server/internal/usecase/gateway/redis.go | 8 ++ server/internal/usecase/interactor/common.go | 5 +- server/internal/usecase/interactor/style.go | 66 +++++++++- server/pkg/scene/style.go | 28 +++-- server/pkg/scene/style_builder.go | 12 +- 21 files changed, 346 insertions(+), 88 deletions(-) create mode 100644 server/internal/infrastructure/redis/redis_adapter.go create mode 100644 server/internal/usecase/gateway/redis.go diff --git a/.gitignore b/.gitignore index baf61eec79..eead3259ef 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules /mongo /data +/redis /.env /.env.* /.idea diff --git a/docker-compose.yml b/docker-compose.yml index ea81b72d9e..edc29af4a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3' +version: "3" services: reearth: image: reearth/reearth:latest @@ -20,3 +20,9 @@ services: - 27017:27017 volumes: - ./mongo:/data/db + reearth-redis: + image: redis:latest + ports: + - 6379:6379 + volumes: + - ./redis:/data diff --git a/go.work.sum b/go.work.sum index 59bdd70a1a..b32d3172de 100644 --- a/go.work.sum +++ b/go.work.sum @@ -148,13 +148,11 @@ github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwc github.com/apache/arrow/go/v12 v12.0.0 h1:xtZE63VWl7qLdB0JObIXvvhGjoVNrQ9ciIHG2OK5cmc= github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= github.com/aws/aws-sdk-go v1.35.5 h1:doSEOxC0UkirPcle20Rc+1kAhJ4Ip+GSEeZ3nKl7Qlk= -github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d h1:7IjN4QP3c38xhg6wz8R3YjoU+6S9e7xBc0DAVLLIpHE= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chrispappas/golang-generics-set v1.0.1 h1:91l8cInAWTxCPwZ8UNg7qkkPsdFdkYS9hytsd8UJsIU= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -258,6 +256,7 @@ github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpsp github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0 h1:i5VIxp6QB8oWZ8IkK8zrDgeT6ORGIUeiN+61iETwJbI= @@ -354,6 +353,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= diff --git a/server/.env.example b/server/.env.example index 39303e2761..7f0fda2b7d 100644 --- a/server/.env.example +++ b/server/.env.example @@ -6,6 +6,14 @@ REEARTH_HOST_WEB=https://localhost:3000 REEARTH_ASSETBASEURL=https://localhost:8080/assets REEARTH_DEV=false +# Redis +REDIS_HOST=localhost:6379 +REDIS_PASSWORD= +REDIS_DB=0 + +# Uptrace +UPTRACE_DSN=https://token@api.uptrace.dev/project_id + # GCP GOOGLE_CLOUD_PROJECT= GCS_BUCKETNAME= diff --git a/server/Makefile b/server/Makefile index ed74ae7199..5616135916 100644 --- a/server/Makefile +++ b/server/Makefile @@ -16,7 +16,10 @@ run-app: run-db: docker compose -f ../docker-compose.yml up -d reearth-mongo +run-redis: + docker compose -f ../docker-compose.yml up -d reearth-redis + gql: go generate ./internal/adapter/gql -.PHONY: lint test e2e build run-app run-db gql +.PHONY: lint test e2e build run-app run-db run-redis gql diff --git a/server/e2e/common.go b/server/e2e/common.go index 12d3c0fba2..83dc77f454 100644 --- a/server/e2e/common.go +++ b/server/e2e/common.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/gavv/httpexpect/v2" + "github.com/go-redis/redis/v8" "github.com/reearth/reearth/server/internal/app" "github.com/reearth/reearth/server/internal/app/config" "github.com/reearth/reearth/server/internal/infrastructure/fs" "github.com/reearth/reearth/server/internal/infrastructure/memory" "github.com/reearth/reearth/server/internal/infrastructure/mongo" + infraRedis "github.com/reearth/reearth/server/internal/infrastructure/redis" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/repo" "github.com/reearth/reearthx/account/accountinfrastructure/accountmongo" @@ -80,12 +82,27 @@ func StartServerWithRepos(t *testing.T, cfg *config.Config, repos *repo.Containe t.Fatalf("server failed to listen: %v", err) } + var redisAdapter *infraRedis.RedisAdapter + if cfg.RedisHost != "" { + redisClient := redis.NewClient(&redis.Options{ + Addr: cfg.RedisHost, + Password: "", + DB: 0, + }) + _, err = redisClient.Ping(ctx).Result() + if err != nil { + t.Fatalf("Failed to connect to Redis: %+v\n", err) + } + redisAdapter = infraRedis.NewRedisAdapter(redisClient) + } + srv := app.NewServer(ctx, &app.ServerConfig{ Config: cfg, Repos: repos, Gateways: gateways, Debug: true, AccountRepos: repos.AccountRepos(), + RedisAdapter: redisAdapter, }) ch := make(chan error) diff --git a/server/e2e/gql_style_test.go b/server/e2e/gql_style_test.go index 1e6dc047f4..c08cdd59a7 100644 --- a/server/e2e/gql_style_test.go +++ b/server/e2e/gql_style_test.go @@ -4,6 +4,7 @@ import ( "net/http" "testing" + "github.com/alicebob/miniredis/v2" "github.com/gavv/httpexpect/v2" "github.com/reearth/reearth/server/internal/app/config" ) @@ -175,11 +176,18 @@ func fetchSceneForStyles(e *httpexpect.Expect, sID string) (GraphQLRequest, *htt } func TestStyleCRUD(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, true, baseSeeder) pId := createProject(e) @@ -216,13 +224,24 @@ func TestStyleCRUD(t *testing.T) { Value("styles").Array().First().Object(). Value("name").Equal("NewName") + // Update Style With Using Redis + _, _ = updateStyleName(e, styleId, "NewNameWithUsingRedis") + + _, res4 := fetchSceneForStyles(e, sId) + + res4.Object(). + Value("data").Object(). + Value("node").Object(). + Value("styles").Array().First().Object(). + Value("name").Equal("NewNameWithUsingRedis") + // Duplicate Style _, duplicateRes := duplicateStyle(e, styleId) duplicatedStyleId := duplicateRes.Path("$.data.duplicateStyle.style.id").Raw().(string) - _, res4 := fetchSceneForStyles(e, sId) + _, res5 := fetchSceneForStyles(e, sId) - res4.Object(). + res5.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). @@ -231,9 +250,9 @@ func TestStyleCRUD(t *testing.T) { // Remove Style _, _ = removeStyle(e, styleId) - _, res5 := fetchSceneForStyles(e, sId) + _, res6 := fetchSceneForStyles(e, sId) - res5.Object(). + res6.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). @@ -241,9 +260,9 @@ func TestStyleCRUD(t *testing.T) { _, _ = removeStyle(e, duplicatedStyleId) - _, res6 := fetchSceneForStyles(e, sId) + _, res7 := fetchSceneForStyles(e, sId) - res6.Object(). + res7.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). diff --git a/server/e2e/ping_test.go b/server/e2e/ping_test.go index c34bd03236..6950f0e949 100644 --- a/server/e2e/ping_test.go +++ b/server/e2e/ping_test.go @@ -4,15 +4,23 @@ import ( "net/http" "testing" + "github.com/alicebob/miniredis/v2" "github.com/reearth/reearth/server/internal/app/config" ) func TestPingAPI(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, false, nil) e.OPTIONS("/api/ping"). diff --git a/server/go.mod b/server/go.mod index 15bc209965..d603837977 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,12 +5,14 @@ require ( cloud.google.com/go/storage v1.36.0 github.com/99designs/gqlgen v0.17.43 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.21.0 + github.com/alicebob/miniredis/v2 v2.32.1 github.com/avast/retry-go/v4 v4.0.4 github.com/aws/aws-sdk-go-v2 v1.25.3 github.com/aws/aws-sdk-go-v2/config v1.27.7 github.com/aws/aws-sdk-go-v2/service/s3 v1.52.0 github.com/blang/semver v3.5.1+incompatible github.com/gavv/httpexpect/v2 v2.3.1 + github.com/go-redis/redis/v8 v8.11.5 github.com/goccy/go-yaml v1.11.3 github.com/google/uuid v1.6.0 github.com/iancoleman/strcase v0.3.0 @@ -34,16 +36,18 @@ require ( github.com/twpayne/go-kml v1.5.2 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/uber/jaeger-lib v2.4.1+incompatible + github.com/uptrace/uptrace-go v1.24.0 github.com/vektah/dataloaden v0.3.0 github.com/vektah/gqlparser/v2 v2.5.11 + github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/zitadel/oidc v1.13.5 go.mongodb.org/mongo-driver v1.13.1 go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.32.0 go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.32.0 - go.opentelemetry.io/otel v1.22.0 - go.opentelemetry.io/otel/sdk v1.22.0 + go.opentelemetry.io/otel v1.24.0 + go.opentelemetry.io/otel/sdk v1.24.0 golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - golang.org/x/net v0.20.0 + golang.org/x/net v0.22.0 golang.org/x/oauth2 v0.16.0 golang.org/x/text v0.14.0 golang.org/x/tools v0.17.0 @@ -64,6 +68,7 @@ require ( github.com/ajg/form v1.5.1 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/andybalholm/brotli v1.0.2 // indirect github.com/auth0/go-jwt-middleware/v2 v2.2.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect @@ -82,8 +87,11 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 // indirect github.com/aws/smithy-go v1.20.1 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fatih/color v1.16.0 // indirect github.com/fatih/structs v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -93,7 +101,7 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect @@ -105,6 +113,7 @@ require ( github.com/gorilla/schema v1.2.0 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/imkira/go-interpol v1.0.0 // indirect @@ -132,6 +141,7 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.27.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -143,28 +153,36 @@ require ( github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect github.com/zitadel/logging v0.3.4 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib v1.22.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect - go.opentelemetry.io/otel/metric v1.22.0 // indirect - go.opentelemetry.io/otel/trace v1.22.0 // indirect + go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/proto/otlp v1.1.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.18.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect - google.golang.org/grpc v1.61.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/go-jose/go-jose.v2 v2.6.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/server/go.sum b/server/go.sum index 3a6dfb0b38..a86bef5ae2 100644 --- a/server/go.sum +++ b/server/go.sum @@ -103,6 +103,10 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis/v2 v2.32.1 h1:Bz7CciDnYSaa0mX5xODh6GUITRSx+cVhjNoOR4JssBo= +github.com/alicebob/miniredis/v2 v2.32.1/go.mod h1:AqkLNAfUm0K07J28hnAyyQKf/x0YkCY/g5DCtuL01Mw= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= @@ -159,9 +163,13 @@ github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -175,13 +183,15 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dgryski/trifles v0.0.0-20200705224438-cafc02a1ee2b h1:8xx0j7yceTAgVxonE+qOOepmwWS/Ic3OLQapY9HJajc= github.com/dgryski/trifles v0.0.0-20200705224438-cafc02a1ee2b/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= @@ -195,8 +205,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fasthttp/websocket v1.4.3-rc.6 h1:omHqsl8j+KXpmzRjF8bmzOSYJ8GnS0E3efi1wYT+niY= github.com/fasthttp/websocket v1.4.3-rc.6/go.mod h1:43W9OM2T8FeXpCWMsBd9Cb7nE2CACNqNvCqQCoty/Lc= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= @@ -207,6 +217,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gavv/httpexpect/v2 v2.3.1 h1:sGLlKMn8AuHS9ztK9Sb7AJ7OxIL8v2PcLdyxfKt1Fo4= github.com/gavv/httpexpect/v2 v2.3.1/go.mod h1:yOE8m/aqFYQDNrgprMeXgq4YynfN9h1NgcE1+1suV64= @@ -228,6 +240,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -297,8 +311,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -385,6 +399,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -392,7 +408,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -441,6 +456,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -484,15 +501,17 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/paulmach/go.geojson v1.4.0 h1:5x5moCkCtDo5x8af62P9IOAYGQcYHtxz2QJ3x1DoCgY= @@ -516,6 +535,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -583,6 +604,8 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uptrace/uptrace-go v1.24.0 h1:UTGl5GImIf3Dqg9obWmu7K4n4YOyhMfJcCGIU83wxbI= +github.com/uptrace/uptrace-go v1.24.0/go.mod h1:pD2GdmZO5q4iic2Yd9rT3uj/euWhosyS19x1L/7Wq+g= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -597,6 +620,10 @@ github.com/vektah/dataloaden v0.3.0 h1:ZfVN2QD6swgvp+tDqdH/OIT/wu3Dhu0cus0k5gIZS github.com/vektah/dataloaden v0.3.0/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= @@ -633,6 +660,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM= github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0= github.com/zitadel/oidc v1.13.5 h1:7jhh68NGZitLqwLiVU9Dtwa4IraJPFF1vS+4UupO93U= @@ -660,23 +689,37 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0 h1:dg9y+7ArpumB6zwImJv47RHfdgOGQ1EMkzP5vLkEnTU= +go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0/go.mod h1:Ul4MtXqu/hJBM+v7a6dCF0nHwckPMLpIpLeCi4+zfdw= go.opentelemetry.io/contrib/propagators/b3 v1.7.0 h1:oRAenUhj+GFttfIp3gj7HYVzBhPOHgq/dWPDSmLCXSY= go.opentelemetry.io/contrib/propagators/b3 v1.7.0/go.mod h1:gXx7AhL4xXCF42gpm9dQvdohoDa2qeyEx4eIIxqK+h4= go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= -go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= -go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0 h1:f2jriWfOdldanBwS9jNBdeOKAQN7b4ugAMaNu1/1k9g= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0/go.mod h1:B+bcQI1yTY+N0vqMpoZbEN7+XU4tNM0DmUiOwebFJWI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/sdk/metric v1.24.0 h1:yyMQrPzF+k88/DbH7o4FMAs80puqd+9osbiBrJrz/w8= +go.opentelemetry.io/otel/sdk/metric v1.24.0/go.mod h1:I6Y5FjH6rvEnTTAYQz3Mmv2kl6Ek5IIrmwTLqMrrOE0= go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= @@ -696,8 +739,8 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -784,8 +827,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -828,6 +871,7 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -901,8 +945,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1121,10 +1165,10 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe h1:0poefMBYvYbs7g5UkjS6HcxBPaTRAmznle9jnxYoAI8= -google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1155,8 +1199,8 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= -google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1172,17 +1216,16 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-jose/go-jose.v2 v2.6.2 h1:Rl5+9rA0kG3vsO1qhncMPRT5eHICihAMQYJkD7u/i4M= gopkg.in/go-jose/go-jose.v2 v2.6.2/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= diff --git a/server/internal/adapter/gql/resolver_mutation_style.go b/server/internal/adapter/gql/resolver_mutation_style.go index b20a1d9fc0..0e4ad6dd8b 100644 --- a/server/internal/adapter/gql/resolver_mutation_style.go +++ b/server/internal/adapter/gql/resolver_mutation_style.go @@ -6,6 +6,7 @@ import ( "github.com/reearth/reearth/server/internal/adapter/gql/gqlmodel" "github.com/reearth/reearth/server/internal/usecase/interfaces" "github.com/reearth/reearth/server/pkg/id" + "go.opentelemetry.io/otel" ) func (r *mutationResolver) AddStyle(ctx context.Context, input gqlmodel.AddStyleInput) (*gqlmodel.AddStylePayload, error) { @@ -29,6 +30,10 @@ func (r *mutationResolver) AddStyle(ctx context.Context, input gqlmodel.AddStyle } func (r *mutationResolver) UpdateStyle(ctx context.Context, input gqlmodel.UpdateStyleInput) (*gqlmodel.UpdateStylePayload, error) { + tracer := otel.Tracer("gql") + ctx, span := tracer.Start(ctx, "mutationResolver.UpdateStyle") + defer span.End() + sid, err := gqlmodel.ToID[id.Style](input.StyleID) if err != nil { return nil, err diff --git a/server/internal/app/app.go b/server/internal/app/app.go index cd60eec630..34ef4ecbb9 100644 --- a/server/internal/app/app.go +++ b/server/internal/app/app.go @@ -95,7 +95,7 @@ func initEcho(ctx context.Context, cfg *ServerConfig) *echo.Echo { } } - e.Use(UsecaseMiddleware(cfg.Repos, cfg.Gateways, cfg.AccountRepos, cfg.AccountGateways, interactor.ContainerConfig{ + e.Use(UsecaseMiddleware(cfg.Repos, cfg.Gateways, cfg.AccountRepos, cfg.AccountGateways, cfg.RedisAdapter, interactor.ContainerConfig{ SignupSecret: cfg.Config.SignupSecret, PublishedIndexHTML: publishedIndexHTML, PublishedIndexURL: cfg.Config.Published.IndexURL, diff --git a/server/internal/app/config/config.go b/server/internal/app/config/config.go index a740a43c47..434adfb90c 100644 --- a/server/internal/app/config/config.go +++ b/server/internal/app/config/config.go @@ -69,6 +69,14 @@ type Config struct { // system extensions Ext_Plugin []string `pp:",omitempty"` + + // redis + RedisHost string `envconfig:"REDIS_HOST" default:"localhost:6379"` + RedisPassword string `envconfig:"REDIS_PASSWORD" default:""` + RedisDB int `envconfig:"REDIS_DB" default:"0"` + + // uptrace + UptraceDSN string `envconfig:"UPTRACE_DSN" pp:",omitempty"` } func ReadConfig(debug bool) (*Config, error) { diff --git a/server/internal/app/main.go b/server/internal/app/main.go index 24fdae2abe..ab16df5df4 100644 --- a/server/internal/app/main.go +++ b/server/internal/app/main.go @@ -7,13 +7,16 @@ import ( "os" "os/signal" + "github.com/go-redis/redis/v8" "github.com/labstack/echo/v4" "github.com/reearth/reearth/server/internal/app/config" + infraRedis "github.com/reearth/reearth/server/internal/infrastructure/redis" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/repo" "github.com/reearth/reearthx/account/accountusecase/accountgateway" "github.com/reearth/reearthx/account/accountusecase/accountrepo" "github.com/reearth/reearthx/log" + "github.com/uptrace/uptrace-go/uptrace" "golang.org/x/net/http2" ) @@ -45,6 +48,30 @@ func Start(debug bool, version string) { // Init repositories repos, gateways, acRepos, acGateways := initReposAndGateways(ctx, conf, debug) + // Redis + redisClient := redis.NewClient(&redis.Options{ + Addr: conf.RedisHost, + Password: conf.RedisPassword, + DB: conf.RedisDB, + }) + _, err := redisClient.Ping(ctx).Result() + if err != nil { + log.Fatalf("Failed to connect to Redis: %+v\n", err) + } + redisAdapter := infraRedis.NewRedisAdapter(redisClient) + + // Init uptrace + uptrace.ConfigureOpentelemetry( + uptrace.WithDSN(conf.UptraceDSN), + uptrace.WithServiceName("reearth"), + uptrace.WithServiceVersion("1.0.0"), + ) + defer func() { + if err := uptrace.Shutdown(ctx); err != nil { + log.Fatalf("failed to shutdown uptrace: %v", err) + } + }() + // Start web server NewServer(ctx, &ServerConfig{ Config: conf, @@ -53,6 +80,7 @@ func Start(debug bool, version string) { AccountRepos: acRepos, Gateways: gateways, AccountGateways: acGateways, + RedisAdapter: redisAdapter, }).Run() } @@ -68,6 +96,7 @@ type ServerConfig struct { AccountRepos *accountrepo.Container Gateways *gateway.Container AccountGateways *accountgateway.Container + RedisAdapter *infraRedis.RedisAdapter } func NewServer(ctx context.Context, cfg *ServerConfig) *WebServer { diff --git a/server/internal/app/usecase.go b/server/internal/app/usecase.go index c5fce3f8f9..b5fc43c2e9 100644 --- a/server/internal/app/usecase.go +++ b/server/internal/app/usecase.go @@ -5,6 +5,7 @@ import ( "github.com/labstack/echo/v4" "github.com/reearth/reearth/server/internal/adapter" + infraRedis "github.com/reearth/reearth/server/internal/infrastructure/redis" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interactor" "github.com/reearth/reearth/server/internal/usecase/repo" @@ -12,7 +13,7 @@ import ( "github.com/reearth/reearthx/account/accountusecase/accountrepo" ) -func UsecaseMiddleware(r *repo.Container, g *gateway.Container, ar *accountrepo.Container, ag *accountgateway.Container, config interactor.ContainerConfig) echo.MiddlewareFunc { +func UsecaseMiddleware(r *repo.Container, g *gateway.Container, ar *accountrepo.Container, ag *accountgateway.Container, redisAdapter *infraRedis.RedisAdapter, config interactor.ContainerConfig) echo.MiddlewareFunc { return ContextMiddleware(func(ctx context.Context) context.Context { repos := r @@ -36,7 +37,7 @@ func UsecaseMiddleware(r *repo.Container, g *gateway.Container, ar *accountrepo. ar2 = ar } - uc := interactor.NewContainer(repos, g, ar2, ag, config) + uc := interactor.NewContainer(repos, g, ar2, ag, redisAdapter, config) ctx = adapter.AttachUsecases(ctx, &uc) return ctx }) diff --git a/server/internal/infrastructure/redis/redis_adapter.go b/server/internal/infrastructure/redis/redis_adapter.go new file mode 100644 index 0000000000..cfd186f733 --- /dev/null +++ b/server/internal/infrastructure/redis/redis_adapter.go @@ -0,0 +1,23 @@ +package redis + +import ( + "context" + + "github.com/go-redis/redis/v8" +) + +type RedisAdapter struct { + client *redis.Client +} + +func NewRedisAdapter(client *redis.Client) *RedisAdapter { + return &RedisAdapter{client: client} +} + +func (r *RedisAdapter) GetValue(ctx context.Context, key string) (string, error) { + return r.client.Get(ctx, key).Result() +} + +func (r *RedisAdapter) SetValue(ctx context.Context, key string, value interface{}) error { + return r.client.Set(ctx, key, value, 0).Err() +} diff --git a/server/internal/usecase/gateway/redis.go b/server/internal/usecase/gateway/redis.go new file mode 100644 index 0000000000..cb30de1fca --- /dev/null +++ b/server/internal/usecase/gateway/redis.go @@ -0,0 +1,8 @@ +package gateway + +import "context" + +type RedisGateway interface { + GetValue(ctx context.Context, key string) (string, error) + SetValue(ctx context.Context, key string, value interface{}) error +} diff --git a/server/internal/usecase/interactor/common.go b/server/internal/usecase/interactor/common.go index 0bf7fc22b6..4a4fb0f8d2 100644 --- a/server/internal/usecase/interactor/common.go +++ b/server/internal/usecase/interactor/common.go @@ -5,6 +5,7 @@ import ( "errors" "net/url" + infraRedis "github.com/reearth/reearth/server/internal/infrastructure/redis" "github.com/reearth/reearth/server/internal/usecase" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interfaces" @@ -28,7 +29,7 @@ type ContainerConfig struct { func NewContainer(r *repo.Container, g *gateway.Container, ar *accountrepo.Container, ag *accountgateway.Container, - config ContainerConfig) interfaces.Container { + redisAdapter *infraRedis.RedisAdapter, config ContainerConfig) interfaces.Container { var published interfaces.Published if config.PublishedIndexURL != nil && config.PublishedIndexURL.String() != "" { published = NewPublishedWithURL(r.Project, r.Storytelling, g.File, config.PublishedIndexURL) @@ -41,7 +42,7 @@ func NewContainer(r *repo.Container, g *gateway.Container, Dataset: NewDataset(r, g), Layer: NewLayer(r), NLSLayer: NewNLSLayer(r), - Style: NewStyle(r), + Style: NewStyle(r, redisAdapter), Plugin: NewPlugin(r, g), Policy: NewPolicy(r), Project: NewProject(r, g), diff --git a/server/internal/usecase/interactor/style.go b/server/internal/usecase/interactor/style.go index 7483e7607c..d3685675bc 100644 --- a/server/internal/usecase/interactor/style.go +++ b/server/internal/usecase/interactor/style.go @@ -3,13 +3,17 @@ package interactor import ( "context" + "github.com/go-redis/redis/v8" "github.com/reearth/reearth/server/internal/usecase" + "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interfaces" "github.com/reearth/reearth/server/internal/usecase/repo" "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/scene" "github.com/reearth/reearth/server/pkg/scene/sceneops" "github.com/reearth/reearthx/usecasex" + "github.com/vmihailenco/msgpack/v5" + "go.opentelemetry.io/otel" ) type Style struct { @@ -18,14 +22,16 @@ type Style struct { styleRepo repo.Style sceneLockRepo repo.SceneLock transaction usecasex.Transaction + redis gateway.RedisGateway } -func NewStyle(r *repo.Container) interfaces.Style { +func NewStyle(r *repo.Container, redis gateway.RedisGateway) interfaces.Style { return &Style{ commonSceneLock: commonSceneLock{sceneLockRepo: r.SceneLock}, styleRepo: r.Style, sceneLockRepo: r.SceneLock, transaction: r.Transaction, + redis: redis, } } @@ -72,24 +78,72 @@ func (i *Style) AddStyle(ctx context.Context, param interfaces.AddStyleInput, op } func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInput, operator *usecase.Operator) (*scene.Style, error) { + tr := otel.Tracer("interactor") + _, span := tr.Start(ctx, "Style.UpdateStyle") + defer span.End() tx, err := i.transaction.Begin(ctx) - if err != nil { + span.RecordError(err) return nil, err } ctx = tx.Context() - defer func() { if err2 := tx.End(ctx); err == nil && err2 != nil { + span.RecordError(err2) err = err2 } }() - style, err := i.styleRepo.FindByID(ctx, param.StyleID) - if err != nil { - return nil, err + var style *scene.Style + cacheKey := scene.StyleCacheKey(param.StyleID) + + _, redisSpan := tr.Start(ctx, "Style.UpdateStyle.RedisGetValue") + val, redisGetErr := i.redis.GetValue(ctx, cacheKey) + if redisGetErr != nil && redisGetErr != redis.Nil { + redisSpan.RecordError(redisGetErr) + redisSpan.End() + return nil, redisGetErr + } + redisSpan.End() + + if redisGetErr == redis.Nil || val == "" { + _, dbSpan := tr.Start(ctx, "Style.UpdateStyle.DBFindById") + style, err = i.styleRepo.FindByID(ctx, param.StyleID) + if err != nil { + dbSpan.RecordError(err) + dbSpan.End() + return nil, err + } + dbSpan.End() + + if style == nil { + return nil, nil + } + + _, dbSpan = tr.Start(ctx, "Style.UpdateStyle.MsgpackMarshal") + msgpackData, err := msgpack.Marshal(&style) + if err != nil { + dbSpan.RecordError(err) + dbSpan.End() + return nil, err + } + dbSpan.End() + + _, dbSpan = tr.Start(ctx, "Style.UpdateStyle.RedisSetValue") + err = i.redis.SetValue(ctx, cacheKey, msgpackData) + if err != nil { + dbSpan.RecordError(err) + dbSpan.End() + return nil, err + } + dbSpan.End() + } else { + err := msgpack.Unmarshal([]byte(val), &style) + if err != nil { + return nil, err + } } if param.Name != nil { diff --git a/server/pkg/scene/style.go b/server/pkg/scene/style.go index 90bf1c36a0..47badb99fc 100644 --- a/server/pkg/scene/style.go +++ b/server/pkg/scene/style.go @@ -1,49 +1,51 @@ package scene +import "fmt" + type Style struct { - id StyleID - name string - value *StyleValue - scene ID + IDField StyleID `msgpack:"IDField"` + NameField string `msgpack:"NameField"` + ValueField *StyleValue `msgpack:"ValueField"` + SceneField ID `msgpack:"SceneField"` } func (s *Style) ID() StyleID { if s == nil { return StyleID{} } - return s.id + return s.IDField } func (s *Style) Name() string { if s == nil { return "" } - return s.name + return s.NameField } func (s *Style) Value() *StyleValue { if s == nil { return nil } - return s.value + return s.ValueField } func (s *Style) Rename(name string) { if s == nil { return } - s.name = name + s.NameField = name } func (s *Style) UpdateValue(sv *StyleValue) { if s == nil { return } - s.value = sv + s.ValueField = sv } func (l *Style) Scene() ID { - return l.scene + return l.SceneField } func (s *Style) Duplicate() *Style { @@ -51,5 +53,9 @@ func (s *Style) Duplicate() *Style { return nil } - return NewStyle().NewID().Name(s.name).Value(s.value).Scene(s.scene).MustBuild() + return NewStyle().NewID().Name(s.NameField).Value(s.ValueField).Scene(s.SceneField).MustBuild() +} + +func StyleCacheKey(id StyleID) string { + return fmt.Sprintf("style:%s", id) } diff --git a/server/pkg/scene/style_builder.go b/server/pkg/scene/style_builder.go index f3a1b97064..32b3963df4 100644 --- a/server/pkg/scene/style_builder.go +++ b/server/pkg/scene/style_builder.go @@ -9,7 +9,7 @@ func NewStyle() *StyleBuilder { } func (b *StyleBuilder) Build() (*Style, error) { - if b.s.id.IsNil() { + if b.s.IDField.IsNil() { return nil, ErrInvalidID } return b.s, nil @@ -24,26 +24,26 @@ func (b *StyleBuilder) MustBuild() *Style { } func (b *StyleBuilder) ID(id StyleID) *StyleBuilder { - b.s.id = id + b.s.IDField = id return b } func (b *StyleBuilder) NewID() *StyleBuilder { - b.s.id = NewStyleID() + b.s.IDField = NewStyleID() return b } func (b *StyleBuilder) Scene(scene ID) *StyleBuilder { - b.s.scene = scene + b.s.SceneField = scene return b } func (b *StyleBuilder) Value(sv *StyleValue) *StyleBuilder { - b.s.value = sv + b.s.ValueField = sv return b } func (b *StyleBuilder) Name(n string) *StyleBuilder { - b.s.name = n + b.s.NameField = n return b } From 895ef3c02203473edf4bc707b697971fafdc89c5 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 11 Apr 2024 23:00:18 +0900 Subject: [PATCH 02/19] feat(server): in-memory cache support for style --- server/e2e/gql_style_test.go | 23 +--- .../infrastructure/redis/redis_adapter.go | 4 + server/internal/usecase/gateway/redis.go | 1 + server/internal/usecase/interactor/style.go | 118 +++++++++++++----- 4 files changed, 96 insertions(+), 50 deletions(-) diff --git a/server/e2e/gql_style_test.go b/server/e2e/gql_style_test.go index c08cdd59a7..bd0a5e1350 100644 --- a/server/e2e/gql_style_test.go +++ b/server/e2e/gql_style_test.go @@ -224,24 +224,13 @@ func TestStyleCRUD(t *testing.T) { Value("styles").Array().First().Object(). Value("name").Equal("NewName") - // Update Style With Using Redis - _, _ = updateStyleName(e, styleId, "NewNameWithUsingRedis") - - _, res4 := fetchSceneForStyles(e, sId) - - res4.Object(). - Value("data").Object(). - Value("node").Object(). - Value("styles").Array().First().Object(). - Value("name").Equal("NewNameWithUsingRedis") - // Duplicate Style _, duplicateRes := duplicateStyle(e, styleId) duplicatedStyleId := duplicateRes.Path("$.data.duplicateStyle.style.id").Raw().(string) - _, res5 := fetchSceneForStyles(e, sId) + _, res4 := fetchSceneForStyles(e, sId) - res5.Object(). + res4.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). @@ -250,9 +239,9 @@ func TestStyleCRUD(t *testing.T) { // Remove Style _, _ = removeStyle(e, styleId) - _, res6 := fetchSceneForStyles(e, sId) + _, res5 := fetchSceneForStyles(e, sId) - res6.Object(). + res5.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). @@ -260,9 +249,9 @@ func TestStyleCRUD(t *testing.T) { _, _ = removeStyle(e, duplicatedStyleId) - _, res7 := fetchSceneForStyles(e, sId) + _, res6 := fetchSceneForStyles(e, sId) - res7.Object(). + res6.Object(). Value("data").Object(). Value("node").Object(). Value("styles").Array(). diff --git a/server/internal/infrastructure/redis/redis_adapter.go b/server/internal/infrastructure/redis/redis_adapter.go index cfd186f733..6110a78d53 100644 --- a/server/internal/infrastructure/redis/redis_adapter.go +++ b/server/internal/infrastructure/redis/redis_adapter.go @@ -21,3 +21,7 @@ func (r *RedisAdapter) GetValue(ctx context.Context, key string) (string, error) func (r *RedisAdapter) SetValue(ctx context.Context, key string, value interface{}) error { return r.client.Set(ctx, key, value, 0).Err() } + +func (r *RedisAdapter) RemoveValue(ctx context.Context, key string) error { + return r.client.Del(ctx, key).Err() +} diff --git a/server/internal/usecase/gateway/redis.go b/server/internal/usecase/gateway/redis.go index cb30de1fca..963f981e47 100644 --- a/server/internal/usecase/gateway/redis.go +++ b/server/internal/usecase/gateway/redis.go @@ -5,4 +5,5 @@ import "context" type RedisGateway interface { GetValue(ctx context.Context, key string) (string, error) SetValue(ctx context.Context, key string, value interface{}) error + RemoveValue(ctx context.Context, key string) error } diff --git a/server/internal/usecase/interactor/style.go b/server/internal/usecase/interactor/style.go index d3685675bc..f864b755e8 100644 --- a/server/internal/usecase/interactor/style.go +++ b/server/internal/usecase/interactor/style.go @@ -74,6 +74,12 @@ func (i *Style) AddStyle(ctx context.Context, param interfaces.AddStyleInput, op } tx.Commit() + + err = i.setStyleToCache(ctx, style.ID(), style) + if err != nil { + return nil, err + } + return style, nil } @@ -97,18 +103,16 @@ func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInp }() var style *scene.Style - cacheKey := scene.StyleCacheKey(param.StyleID) - _, redisSpan := tr.Start(ctx, "Style.UpdateStyle.RedisGetValue") - val, redisGetErr := i.redis.GetValue(ctx, cacheKey) - if redisGetErr != nil && redisGetErr != redis.Nil { - redisSpan.RecordError(redisGetErr) + style, err = i.getStyleFromCache(ctx, param.StyleID) + if err != nil { + redisSpan.RecordError(err) redisSpan.End() - return nil, redisGetErr + return nil, err } redisSpan.End() - if redisGetErr == redis.Nil || val == "" { + if style == nil { _, dbSpan := tr.Start(ctx, "Style.UpdateStyle.DBFindById") style, err = i.styleRepo.FindByID(ctx, param.StyleID) if err != nil { @@ -121,29 +125,6 @@ func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInp if style == nil { return nil, nil } - - _, dbSpan = tr.Start(ctx, "Style.UpdateStyle.MsgpackMarshal") - msgpackData, err := msgpack.Marshal(&style) - if err != nil { - dbSpan.RecordError(err) - dbSpan.End() - return nil, err - } - dbSpan.End() - - _, dbSpan = tr.Start(ctx, "Style.UpdateStyle.RedisSetValue") - err = i.redis.SetValue(ctx, cacheKey, msgpackData) - if err != nil { - dbSpan.RecordError(err) - dbSpan.End() - return nil, err - } - dbSpan.End() - } else { - err := msgpack.Unmarshal([]byte(val), &style) - if err != nil { - return nil, err - } } if param.Name != nil { @@ -159,6 +140,15 @@ func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInp } tx.Commit() + + _, dbSpan := tr.Start(ctx, "Style.UpdateStyle.RedisSetValue") + err = i.setStyleToCache(ctx, style.ID(), style) + if err != nil { + dbSpan.RecordError(err) + dbSpan.End() + return nil, err + } + return style, nil } @@ -175,16 +165,24 @@ func (i *Style) RemoveStyle(ctx context.Context, styleID id.StyleID, operator *u } }() - s, err := i.styleRepo.FindByID(ctx, styleID) + var style *scene.Style + style, err = i.getStyleFromCache(ctx, styleID) if err != nil { return styleID, err } + if style == nil { + style, err = i.styleRepo.FindByID(ctx, styleID) + if err != nil { + return styleID, err + } + } + // if err := i.CanWriteScene(s.Scene(), operator); err != nil { // return styleID, err // } - if err := i.CheckSceneLock(ctx, s.Scene()); err != nil { + if err := i.CheckSceneLock(ctx, style.Scene()); err != nil { return styleID, err } @@ -194,6 +192,12 @@ func (i *Style) RemoveStyle(ctx context.Context, styleID id.StyleID, operator *u } tx.Commit() + + err = i.removeStyleFromCache(ctx, styleID) + if err != nil { + return styleID, err + } + return styleID, nil } @@ -210,11 +214,19 @@ func (i *Style) DuplicateStyle(ctx context.Context, styleID id.StyleID, operator } }() - style, err := i.styleRepo.FindByID(ctx, styleID) + var style *scene.Style + style, err = i.getStyleFromCache(ctx, styleID) if err != nil { return nil, err } + if style == nil { + style, err = i.styleRepo.FindByID(ctx, styleID) + if err != nil { + return nil, err + } + } + // if err := i.CanWriteScene(s.Scene(), operator); err != nil { // return nil, err // } @@ -226,5 +238,45 @@ func (i *Style) DuplicateStyle(ctx context.Context, styleID id.StyleID, operator } tx.Commit() + + err = i.setStyleToCache(ctx, duplicatedStyle.ID(), duplicatedStyle) + if err != nil { + return nil, err + } + return duplicatedStyle, nil } + +func (i *Style) getStyleFromCache(ctx context.Context, styleID scene.StyleID) (*scene.Style, error) { + cacheKey := scene.StyleCacheKey(styleID) + val, err := i.redis.GetValue(ctx, cacheKey) + if err != nil { + if err == redis.Nil { + return nil, nil + } + + return nil, err + } + + var style *scene.Style + if err := msgpack.Unmarshal([]byte(val), &style); err != nil { + return nil, err + } + + return style, nil +} + +func (i *Style) setStyleToCache(ctx context.Context, styleID scene.StyleID, style *scene.Style) error { + cacheKey := scene.StyleCacheKey(styleID) + data, err := msgpack.Marshal(style) + if err != nil { + return err + } + + return i.redis.SetValue(ctx, cacheKey, data) +} + +func (i *Style) removeStyleFromCache(ctx context.Context, styleID scene.StyleID) error { + cacheKey := scene.StyleCacheKey(styleID) + return i.redis.RemoveValue(ctx, cacheKey) +} From e5e3d6c59f62e6a5b25d682765b6f6793793179d Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 20:08:30 +0900 Subject: [PATCH 03/19] Refactoring redis --- server/internal/usecase/interactor/common.go | 62 ++++++++++++++++++++ server/internal/usecase/interactor/style.go | 50 +++------------- 2 files changed, 69 insertions(+), 43 deletions(-) diff --git a/server/internal/usecase/interactor/common.go b/server/internal/usecase/interactor/common.go index 4a4fb0f8d2..eb54618e35 100644 --- a/server/internal/usecase/interactor/common.go +++ b/server/internal/usecase/interactor/common.go @@ -5,6 +5,7 @@ import ( "errors" "net/url" + "github.com/go-redis/redis/v8" infraRedis "github.com/reearth/reearth/server/internal/infrastructure/redis" "github.com/reearth/reearth/server/internal/usecase" "github.com/reearth/reearth/server/internal/usecase/gateway" @@ -18,6 +19,7 @@ import ( "github.com/reearth/reearthx/account/accountusecase/accountinteractor" "github.com/reearth/reearthx/account/accountusecase/accountrepo" "github.com/reearth/reearthx/rerror" + "github.com/vmihailenco/msgpack/v5" ) type ContainerConfig struct { @@ -238,3 +240,63 @@ func (d ProjectDeleter) Delete(ctx context.Context, prj *project.Project, force return nil } + +func checkRedisClient(redisClient any) (*infraRedis.RedisAdapter, bool) { + if redisClient == nil { + return nil, false + } + + adapter, ok := redisClient.(*infraRedis.RedisAdapter) + if !ok || adapter == nil { + return nil, false + } + return adapter, true +} + +func getFromCache[T any](ctx context.Context, redisClient any, cacheKey string) (T, error) { + var zero T + + redisAdapter, ok := checkRedisClient(redisClient) + if !ok { + return zero, nil + } + + val, err := redisAdapter.GetValue(ctx, cacheKey) + if err != nil { + if err == redis.Nil { + return zero, nil + } + + return zero, err + } + + var result T + if err := msgpack.Unmarshal([]byte(val), &result); err != nil { + return zero, err + } + + return result, nil +} + +func setToCache[T any](ctx context.Context, redisClient any, cacheKey string, data T) error { + redisAdapter, ok := checkRedisClient(redisClient) + if !ok { + return nil + } + + serializedData, err := msgpack.Marshal(data) + if err != nil { + return err + } + + return redisAdapter.SetValue(ctx, cacheKey, serializedData) +} + +func deleteFromCache(ctx context.Context, redisClient any, cacheKey string) error { + redisAdapter, ok := checkRedisClient(redisClient) + if !ok { + return nil + } + + return redisAdapter.RemoveValue(ctx, cacheKey) +} diff --git a/server/internal/usecase/interactor/style.go b/server/internal/usecase/interactor/style.go index f864b755e8..46f14f1de2 100644 --- a/server/internal/usecase/interactor/style.go +++ b/server/internal/usecase/interactor/style.go @@ -3,7 +3,6 @@ package interactor import ( "context" - "github.com/go-redis/redis/v8" "github.com/reearth/reearth/server/internal/usecase" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interfaces" @@ -12,7 +11,6 @@ import ( "github.com/reearth/reearth/server/pkg/scene" "github.com/reearth/reearth/server/pkg/scene/sceneops" "github.com/reearth/reearthx/usecasex" - "github.com/vmihailenco/msgpack/v5" "go.opentelemetry.io/otel" ) @@ -75,7 +73,7 @@ func (i *Style) AddStyle(ctx context.Context, param interfaces.AddStyleInput, op tx.Commit() - err = i.setStyleToCache(ctx, style.ID(), style) + err = setToCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(style.ID()), style) if err != nil { return nil, err } @@ -104,7 +102,7 @@ func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInp var style *scene.Style _, redisSpan := tr.Start(ctx, "Style.UpdateStyle.RedisGetValue") - style, err = i.getStyleFromCache(ctx, param.StyleID) + style, err = getFromCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(param.StyleID)) if err != nil { redisSpan.RecordError(err) redisSpan.End() @@ -142,7 +140,7 @@ func (i *Style) UpdateStyle(ctx context.Context, param interfaces.UpdateStyleInp tx.Commit() _, dbSpan := tr.Start(ctx, "Style.UpdateStyle.RedisSetValue") - err = i.setStyleToCache(ctx, style.ID(), style) + err = setToCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(style.ID()), style) if err != nil { dbSpan.RecordError(err) dbSpan.End() @@ -166,7 +164,7 @@ func (i *Style) RemoveStyle(ctx context.Context, styleID id.StyleID, operator *u }() var style *scene.Style - style, err = i.getStyleFromCache(ctx, styleID) + style, err = getFromCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(styleID)) if err != nil { return styleID, err } @@ -193,7 +191,7 @@ func (i *Style) RemoveStyle(ctx context.Context, styleID id.StyleID, operator *u tx.Commit() - err = i.removeStyleFromCache(ctx, styleID) + err = deleteFromCache(ctx, i.redis, scene.StyleCacheKey(styleID)) if err != nil { return styleID, err } @@ -215,7 +213,7 @@ func (i *Style) DuplicateStyle(ctx context.Context, styleID id.StyleID, operator }() var style *scene.Style - style, err = i.getStyleFromCache(ctx, styleID) + style, err = getFromCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(styleID)) if err != nil { return nil, err } @@ -239,44 +237,10 @@ func (i *Style) DuplicateStyle(ctx context.Context, styleID id.StyleID, operator tx.Commit() - err = i.setStyleToCache(ctx, duplicatedStyle.ID(), duplicatedStyle) + err = setToCache[*scene.Style](ctx, i.redis, scene.StyleCacheKey(styleID), duplicatedStyle) if err != nil { return nil, err } return duplicatedStyle, nil } - -func (i *Style) getStyleFromCache(ctx context.Context, styleID scene.StyleID) (*scene.Style, error) { - cacheKey := scene.StyleCacheKey(styleID) - val, err := i.redis.GetValue(ctx, cacheKey) - if err != nil { - if err == redis.Nil { - return nil, nil - } - - return nil, err - } - - var style *scene.Style - if err := msgpack.Unmarshal([]byte(val), &style); err != nil { - return nil, err - } - - return style, nil -} - -func (i *Style) setStyleToCache(ctx context.Context, styleID scene.StyleID, style *scene.Style) error { - cacheKey := scene.StyleCacheKey(styleID) - data, err := msgpack.Marshal(style) - if err != nil { - return err - } - - return i.redis.SetValue(ctx, cacheKey, data) -} - -func (i *Style) removeStyleFromCache(ctx context.Context, styleID scene.StyleID) error { - cacheKey := scene.StyleCacheKey(styleID) - return i.redis.RemoveValue(ctx, cacheKey) -} From 7a0923a54f047b3c9b9dd0d3b220b0c9e372efdf Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 20:13:09 +0900 Subject: [PATCH 04/19] fix e2e --- server/e2e/gql_style_test.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/server/e2e/gql_style_test.go b/server/e2e/gql_style_test.go index bd0a5e1350..16fa1cbc45 100644 --- a/server/e2e/gql_style_test.go +++ b/server/e2e/gql_style_test.go @@ -175,19 +175,23 @@ func fetchSceneForStyles(e *httpexpect.Expect, sID string) (GraphQLRequest, *htt return fetchSceneRequestBody, res } -func TestStyleCRUD(t *testing.T) { - mr, err := miniredis.Run() - if err != nil { - t.Fatal(err) +func styleCRUD(t *testing.T, isUseRedis bool) { + redisAddress := "" + if isUseRedis { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + redisAddress = mr.Addr() } - defer mr.Close() e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, - RedisHost: mr.Addr(), + RedisHost: redisAddress, }, true, baseSeeder) pId := createProject(e) @@ -257,3 +261,11 @@ func TestStyleCRUD(t *testing.T) { Value("styles").Array(). Length().Equal(0) } + +func TestStyleCRUD(t *testing.T) { + styleCRUD(t, false) +} + +func TestStyleCRUDWithRedis(t *testing.T) { + styleCRUD(t, true) +} From 136feb2353f5c89c3071d77041ff12b89e2c4955 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 16:14:40 +0900 Subject: [PATCH 05/19] setting redis --- server/internal/usecase/interactor/common.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/usecase/interactor/common.go b/server/internal/usecase/interactor/common.go index eb54618e35..ce4a673c93 100644 --- a/server/internal/usecase/interactor/common.go +++ b/server/internal/usecase/interactor/common.go @@ -43,7 +43,7 @@ func NewContainer(r *repo.Container, g *gateway.Container, Asset: NewAsset(r, g), Dataset: NewDataset(r, g), Layer: NewLayer(r), - NLSLayer: NewNLSLayer(r), + NLSLayer: NewNLSLayer(r, redisAdapter), Style: NewStyle(r, redisAdapter), Plugin: NewPlugin(r, g), Policy: NewPolicy(r), From 0c49cb509371c5e612315838c78c8e51489c1c22 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 16:16:01 +0900 Subject: [PATCH 06/19] fix pkg --- server/pkg/nlslayer/builder.go | 10 +-- server/pkg/nlslayer/group.go | 24 +++--- server/pkg/nlslayer/group_builder.go | 22 ++--- server/pkg/nlslayer/nlslayer.go | 116 ++++++++++++++------------ server/pkg/nlslayer/simple.go | 24 +++--- server/pkg/nlslayer/simple_builder.go | 22 ++--- 6 files changed, 112 insertions(+), 106 deletions(-) diff --git a/server/pkg/nlslayer/builder.go b/server/pkg/nlslayer/builder.go index 0f94901b38..91e0bbcb39 100644 --- a/server/pkg/nlslayer/builder.go +++ b/server/pkg/nlslayer/builder.go @@ -17,26 +17,26 @@ func (b *Builder) Simple() *NLSLayerSimpleBuilder { } func (b *Builder) ID(id ID) *Builder { - b.base.id = id + b.base.IDField = id return b } func (b *Builder) NewID() *Builder { - b.base.id = NewID() + b.base.IDField = NewID() return b } func (b *Builder) Scene(s SceneID) *Builder { - b.base.scene = s + b.base.SceneField = s return b } func (b *Builder) LayerType(t LayerType) *Builder { - b.base.layerType = t + b.base.LayerTypeField = t return b } func (b *Builder) Infobox(infobox *Infobox) *Builder { - b.base.infobox = infobox + b.base.InfoboxField = infobox return b } diff --git a/server/pkg/nlslayer/group.go b/server/pkg/nlslayer/group.go index 2ce14616a1..4b2ee8e147 100644 --- a/server/pkg/nlslayer/group.go +++ b/server/pkg/nlslayer/group.go @@ -22,7 +22,7 @@ func (l *NLSLayerGroup) LayerType() LayerType { } func (l *NLSLayerGroup) Scene() SceneID { - return l.layerBase.scene + return l.layerBase.SceneField } func (l *NLSLayerGroup) Title() string { @@ -33,35 +33,35 @@ func (l *NLSLayerGroup) IsVisible() bool { if l == nil { return false } - return l.layerBase.visible + return l.layerBase.VisibleField } func (l *NLSLayerGroup) HasInfobox() bool { if l == nil { return false } - return l.layerBase.infobox != nil + return l.layerBase.InfoboxField != nil } func (l *NLSLayerGroup) Infobox() *Infobox { if l == nil { return nil } - return l.layerBase.infobox + return l.layerBase.InfoboxField } func (l *NLSLayerGroup) SetVisible(visible bool) { if l == nil { return } - l.layerBase.visible = visible + l.layerBase.VisibleField = visible } func (l *NLSLayerGroup) SetInfobox(infobox *Infobox) { if l == nil { return } - l.layerBase.infobox = infobox + l.layerBase.InfoboxField = infobox } func (l *NLSLayerGroup) Children() *IDList { @@ -86,7 +86,7 @@ func (l *NLSLayerGroup) Config() *Config { if l == nil { return &Config{} } - return l.config + return l.ConfigField } func (l *NLSLayerGroup) IsRoot() bool { @@ -119,33 +119,33 @@ func (l *NLSLayerGroup) IsSketch() bool { if l == nil { return false } - return l.layerBase.isSketch + return l.layerBase.IsSketchField } func (l *NLSLayerGroup) SetIsSketch(isSketch bool) { if l == nil { return } - l.layerBase.isSketch = isSketch + l.layerBase.IsSketchField = isSketch } func (l *NLSLayerGroup) HasSketch() bool { if l == nil { return false } - return l.layerBase.sketch != nil + return l.layerBase.SketchField != nil } func (l *NLSLayerGroup) Sketch() *SketchInfo { if l == nil { return nil } - return l.layerBase.sketch + return l.layerBase.SketchField } func (l *NLSLayerGroup) SetSketch(sketch *SketchInfo) { if l == nil { return } - l.layerBase.sketch = sketch + l.layerBase.SketchField = sketch } diff --git a/server/pkg/nlslayer/group_builder.go b/server/pkg/nlslayer/group_builder.go index 95171351ea..6aff65b797 100644 --- a/server/pkg/nlslayer/group_builder.go +++ b/server/pkg/nlslayer/group_builder.go @@ -28,7 +28,7 @@ func NewNLSLayerGroup() *NLSLayerGroupBuilder { } func (b *NLSLayerGroupBuilder) Build() (*NLSLayerGroup, error) { - if b.l.id.IsNil() { + if b.l.IDField.IsNil() { return nil, ErrInvalidID } return b.l, nil @@ -48,22 +48,22 @@ func (b *NLSLayerGroupBuilder) base(layer layerBase) *NLSLayerGroupBuilder { } func (b *NLSLayerGroupBuilder) ID(id ID) *NLSLayerGroupBuilder { - b.l.id = id + b.l.IDField = id return b } func (b *NLSLayerGroupBuilder) NewID() *NLSLayerGroupBuilder { - b.l.id = NewID() + b.l.IDField = NewID() return b } func (b *NLSLayerGroupBuilder) LayerType(t LayerType) *NLSLayerGroupBuilder { - b.l.layerType = t + b.l.LayerTypeField = t return b } func (b *NLSLayerGroupBuilder) Scene(s SceneID) *NLSLayerGroupBuilder { - b.l.scene = s + b.l.SceneField = s return b } @@ -73,12 +73,12 @@ func (b *NLSLayerGroupBuilder) Layers(ll *IDList) *NLSLayerGroupBuilder { } func (b *NLSLayerGroupBuilder) Config(c *Config) *NLSLayerGroupBuilder { - b.l.config = c + b.l.ConfigField = c return b } func (b *NLSLayerGroupBuilder) Title(t string) *NLSLayerGroupBuilder { - b.l.title = t + b.l.TitleField = t return b } @@ -88,21 +88,21 @@ func (b *NLSLayerGroupBuilder) Root(r bool) *NLSLayerGroupBuilder { } func (b *NLSLayerGroupBuilder) IsVisible(i bool) *NLSLayerGroupBuilder { - b.l.visible = i + b.l.VisibleField = i return b } func (b *NLSLayerGroupBuilder) Infobox(infobox *Infobox) *NLSLayerGroupBuilder { - b.l.infobox = infobox + b.l.InfoboxField = infobox return b } func (b *NLSLayerGroupBuilder) IsSketch(i bool) *NLSLayerGroupBuilder { - b.l.isSketch = i + b.l.IsSketchField = i return b } func (b *NLSLayerGroupBuilder) Sketch(sketch *SketchInfo) *NLSLayerGroupBuilder { - b.l.sketch = sketch + b.l.SketchField = sketch return b } diff --git a/server/pkg/nlslayer/nlslayer.go b/server/pkg/nlslayer/nlslayer.go index 22608f3088..c937036145 100644 --- a/server/pkg/nlslayer/nlslayer.go +++ b/server/pkg/nlslayer/nlslayer.go @@ -1,5 +1,7 @@ package nlslayer +import "fmt" + type NLSLayer interface { Cloner ID() ID @@ -59,90 +61,90 @@ func ToLayerSimpleRef(l *NLSLayer) *NLSLayerSimple { } type layerBase struct { - id ID - layerType LayerType - scene SceneID - title string - visible bool - infobox *Infobox - config *Config - isSketch bool - sketch *SketchInfo + IDField ID `msgpack:"IDField"` + LayerTypeField LayerType `msgpack:"LayerTypeField"` + SceneField SceneID `msgpack:"SceneField"` + TitleField string `msgpack:"TitleField"` + VisibleField bool `msgpack:"VisibleField"` + InfoboxField *Infobox `msgpack:"InfoboxField"` + ConfigField *Config `msgpack:"ConfigField"` + IsSketchField bool `msgpack:"IsSketchField"` + SketchField *SketchInfo `msgpack:"SketchField"` } func (l *layerBase) ID() ID { - return l.id + return l.IDField } func (l *layerBase) IDRef() *ID { if l == nil { return nil } - return l.id.Ref() + return l.IDField.Ref() } func (l *layerBase) LayerType() LayerType { if l == nil { return "" } - return l.layerType + return l.LayerTypeField } func (l *layerBase) Scene() SceneID { - return l.scene + return l.SceneField } func (l *layerBase) Config() *Config { - return l.config + return l.ConfigField } func (l *layerBase) Title() string { if l == nil { return "" } - return l.title + return l.TitleField } func (l *layerBase) IsVisible() bool { if l == nil { return false } - return l.visible + return l.VisibleField } func (l *layerBase) HasInfobox() bool { if l == nil { return false } - return l.infobox != nil + return l.InfoboxField != nil } func (l *layerBase) Infobox() *Infobox { if l == nil { return nil } - return l.infobox + return l.InfoboxField } func (l *layerBase) SetVisible(visible bool) { if l == nil { return } - l.visible = visible + l.VisibleField = visible } func (l *layerBase) SetInfobox(infobox *Infobox) { if l == nil { return } - l.infobox = infobox + l.InfoboxField = infobox } func (l *layerBase) Rename(name string) { if l == nil { return } - l.title = name + l.TitleField = name } func (l *layerBase) UpdateConfig(newConfig *Config) { @@ -150,13 +152,13 @@ func (l *layerBase) UpdateConfig(newConfig *Config) { return } - if l.config == nil { - l.config = newConfig + if l.ConfigField == nil { + l.ConfigField = newConfig return } for key, value := range *newConfig { - (*l.config)[key] = value + (*l.ConfigField)[key] = value } } @@ -165,27 +167,27 @@ func (l *layerBase) Clone() *layerBase { return nil } var clonedConfig *Config - if l.config != nil { - clonedConfigItem := l.config.Clone() + if l.ConfigField != nil { + clonedConfigItem := l.ConfigField.Clone() clonedConfig = &clonedConfigItem } cloned := &layerBase{ - id: l.id, - layerType: l.layerType, - scene: l.scene, - title: l.title, - visible: l.visible, - config: clonedConfig, - isSketch: l.isSketch, + IDField: l.IDField, + LayerTypeField: l.LayerTypeField, + SceneField: l.SceneField, + TitleField: l.TitleField, + VisibleField: l.VisibleField, + ConfigField: clonedConfig, + IsSketchField: l.IsSketchField, } - if l.infobox != nil { - cloned.infobox = l.infobox.Clone() + if l.InfoboxField != nil { + cloned.InfoboxField = l.InfoboxField.Clone() } - if l.sketch != nil { - cloned.sketch = l.sketch.Clone() + if l.SketchField != nil { + cloned.SketchField = l.SketchField.Clone() } return cloned @@ -196,27 +198,27 @@ func (l *layerBase) Duplicate() NLSLayer { return nil } var duplicatedConfig *Config - if l.config != nil { - duplicatedConfigItem := l.config.Clone() + if l.ConfigField != nil { + duplicatedConfigItem := l.ConfigField.Clone() duplicatedConfig = &duplicatedConfigItem } duplicated := &layerBase{ - id: NewID(), - layerType: l.layerType, - scene: l.scene, - title: l.title, - visible: l.visible, - config: duplicatedConfig, - isSketch: l.isSketch, + IDField: NewID(), + LayerTypeField: l.LayerTypeField, + SceneField: l.SceneField, + TitleField: l.TitleField, + VisibleField: l.VisibleField, + ConfigField: duplicatedConfig, + IsSketchField: l.IsSketchField, } - if l.infobox != nil { - duplicated.infobox = l.infobox.Clone() + if l.InfoboxField != nil { + duplicated.InfoboxField = l.InfoboxField.Clone() } - if l.sketch != nil { - duplicated.sketch = l.sketch.Clone() + if l.SketchField != nil { + duplicated.SketchField = l.SketchField.Clone() } return &NLSLayerSimple{layerBase: *duplicated} @@ -226,33 +228,37 @@ func (l *layerBase) IsSketch() bool { if l == nil { return false } - return l.isSketch + return l.IsSketchField } func (l *layerBase) SetIsSketch(isSketch bool) { if l == nil { return } - l.isSketch = isSketch + l.IsSketchField = isSketch } func (l *layerBase) HasSketch() bool { if l == nil { return false } - return l.sketch != nil + return l.SketchField != nil } func (l *layerBase) Sketch() *SketchInfo { if l == nil { return nil } - return l.sketch + return l.SketchField } func (l *layerBase) SetSketchInfo(sketch *SketchInfo) { if l == nil { return } - l.sketch = sketch + l.SketchField = sketch +} + +func NLSLayerCacheKey(id ID) string { + return fmt.Sprintf("NLSLayer:%s", id) } diff --git a/server/pkg/nlslayer/simple.go b/server/pkg/nlslayer/simple.go index 490fc2d655..5b0a4a5e28 100644 --- a/server/pkg/nlslayer/simple.go +++ b/server/pkg/nlslayer/simple.go @@ -24,7 +24,7 @@ func (l *NLSLayerSimple) LayerType() LayerType { } func (l *NLSLayerSimple) Scene() SceneID { - return l.layerBase.scene + return l.layerBase.SceneField } func (l *NLSLayerSimple) LinkedDataset() *pl.DatasetID { @@ -39,35 +39,35 @@ func (l *NLSLayerSimple) IsVisible() bool { if l == nil { return false } - return l.layerBase.visible + return l.layerBase.VisibleField } func (l *NLSLayerSimple) HasInfobox() bool { if l == nil { return false } - return l.layerBase.infobox != nil + return l.layerBase.InfoboxField != nil } func (l *NLSLayerSimple) Infobox() *Infobox { if l == nil { return nil } - return l.layerBase.infobox + return l.layerBase.InfoboxField } func (l *NLSLayerSimple) SetVisible(visible bool) { if l == nil { return } - l.layerBase.visible = visible + l.layerBase.VisibleField = visible } func (l *NLSLayerSimple) SetInfobox(infobox *Infobox) { if l == nil { return } - l.layerBase.infobox = infobox + l.layerBase.InfoboxField = infobox } func (l *NLSLayerSimple) LayerRef() *NLSLayer { @@ -82,7 +82,7 @@ func (l *NLSLayerSimple) Config() *Config { if l == nil { return nil } - return l.config + return l.ConfigField } func (l *NLSLayerSimple) Clone() Cloner { @@ -101,33 +101,33 @@ func (l *NLSLayerSimple) IsSketch() bool { if l == nil { return false } - return l.layerBase.isSketch + return l.layerBase.IsSketchField } func (l *NLSLayerSimple) SetIsSketch(isSketch bool) { if l == nil { return } - l.layerBase.isSketch = isSketch + l.layerBase.IsSketchField = isSketch } func (l *NLSLayerSimple) HasSketch() bool { if l == nil { return false } - return l.layerBase.sketch != nil + return l.layerBase.SketchField != nil } func (l *NLSLayerSimple) Sketch() *SketchInfo { if l == nil { return nil } - return l.layerBase.sketch + return l.layerBase.SketchField } func (l *NLSLayerSimple) SetSketch(sketch *SketchInfo) { if l == nil { return } - l.layerBase.sketch = sketch + l.layerBase.SketchField = sketch } diff --git a/server/pkg/nlslayer/simple_builder.go b/server/pkg/nlslayer/simple_builder.go index 5f7989110a..b63bb008e1 100644 --- a/server/pkg/nlslayer/simple_builder.go +++ b/server/pkg/nlslayer/simple_builder.go @@ -28,7 +28,7 @@ func NewNLSLayerSimple() *NLSLayerSimpleBuilder { } func (b *NLSLayerSimpleBuilder) Build() (*NLSLayerSimple, error) { - if b.l.id.IsNil() { + if b.l.IDField.IsNil() { return nil, ErrInvalidID } return b.l, nil @@ -48,51 +48,51 @@ func (b *NLSLayerSimpleBuilder) base(layer layerBase) *NLSLayerSimpleBuilder { } func (b *NLSLayerSimpleBuilder) ID(id ID) *NLSLayerSimpleBuilder { - b.l.id = id + b.l.IDField = id return b } func (b *NLSLayerSimpleBuilder) NewID() *NLSLayerSimpleBuilder { - b.l.id = NewID() + b.l.IDField = NewID() return b } func (b *NLSLayerSimpleBuilder) LayerType(t LayerType) *NLSLayerSimpleBuilder { - b.l.layerType = t + b.l.LayerTypeField = t return b } func (b *NLSLayerSimpleBuilder) Scene(s SceneID) *NLSLayerSimpleBuilder { - b.l.scene = s + b.l.SceneField = s return b } func (b *NLSLayerSimpleBuilder) Title(t string) *NLSLayerSimpleBuilder { - b.l.title = t + b.l.TitleField = t return b } func (b *NLSLayerSimpleBuilder) IsVisible(i bool) *NLSLayerSimpleBuilder { - b.l.visible = i + b.l.VisibleField = i return b } func (b *NLSLayerSimpleBuilder) Infobox(infobox *Infobox) *NLSLayerSimpleBuilder { - b.l.infobox = infobox + b.l.InfoboxField = infobox return b } func (b *NLSLayerSimpleBuilder) Config(c *Config) *NLSLayerSimpleBuilder { - b.l.config = c + b.l.ConfigField = c return b } func (b *NLSLayerSimpleBuilder) IsSketch(i bool) *NLSLayerSimpleBuilder { - b.l.isSketch = i + b.l.IsSketchField = i return b } func (b *NLSLayerSimpleBuilder) Sketch(sketch *SketchInfo) *NLSLayerSimpleBuilder { - b.l.sketch = sketch + b.l.SketchField = sketch return b } From 44f9299b032d7179455505924d4886ba3494e836 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 16:20:44 +0900 Subject: [PATCH 07/19] fix pkg --- server/pkg/nlslayer/builder.go | 4 +-- server/pkg/nlslayer/group.go | 36 ++++++++++---------- server/pkg/nlslayer/group_builder.go | 6 ++-- server/pkg/nlslayer/nlslayer.go | 48 +++++++++++++-------------- server/pkg/nlslayer/simple.go | 36 ++++++++++---------- server/pkg/nlslayer/simple_builder.go | 6 ++-- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/server/pkg/nlslayer/builder.go b/server/pkg/nlslayer/builder.go index 91e0bbcb39..a7aa88e290 100644 --- a/server/pkg/nlslayer/builder.go +++ b/server/pkg/nlslayer/builder.go @@ -1,11 +1,11 @@ package nlslayer type Builder struct { - base layerBase + base LayerBase } func New() *Builder { - return &Builder{base: layerBase{}} + return &Builder{base: LayerBase{}} } func (b *Builder) Group() *NLSLayerGroupBuilder { diff --git a/server/pkg/nlslayer/group.go b/server/pkg/nlslayer/group.go index 4b2ee8e147..a01358e3d9 100644 --- a/server/pkg/nlslayer/group.go +++ b/server/pkg/nlslayer/group.go @@ -1,67 +1,67 @@ package nlslayer type NLSLayerGroup struct { - layerBase + LayerBase children *IDList root bool } func (l *NLSLayerGroup) ID() ID { - return l.layerBase.ID() + return l.LayerBase.ID() } func (l *NLSLayerGroup) IDRef() *ID { if l == nil { return nil } - return l.layerBase.IDRef() + return l.LayerBase.IDRef() } func (l *NLSLayerGroup) LayerType() LayerType { - return l.layerBase.LayerType() + return l.LayerBase.LayerType() } func (l *NLSLayerGroup) Scene() SceneID { - return l.layerBase.SceneField + return l.LayerBase.SceneField } func (l *NLSLayerGroup) Title() string { - return l.layerBase.Title() + return l.LayerBase.Title() } func (l *NLSLayerGroup) IsVisible() bool { if l == nil { return false } - return l.layerBase.VisibleField + return l.LayerBase.VisibleField } func (l *NLSLayerGroup) HasInfobox() bool { if l == nil { return false } - return l.layerBase.InfoboxField != nil + return l.LayerBase.InfoboxField != nil } func (l *NLSLayerGroup) Infobox() *Infobox { if l == nil { return nil } - return l.layerBase.InfoboxField + return l.LayerBase.InfoboxField } func (l *NLSLayerGroup) SetVisible(visible bool) { if l == nil { return } - l.layerBase.VisibleField = visible + l.LayerBase.VisibleField = visible } func (l *NLSLayerGroup) SetInfobox(infobox *Infobox) { if l == nil { return } - l.layerBase.InfoboxField = infobox + l.LayerBase.InfoboxField = infobox } func (l *NLSLayerGroup) Children() *IDList { @@ -101,7 +101,7 @@ func (l *NLSLayerGroup) Clone() Cloner { return nil } - clonedBase := l.layerBase.Clone() + clonedBase := l.LayerBase.Clone() var clonedChildren *IDList if l.children != nil { @@ -109,7 +109,7 @@ func (l *NLSLayerGroup) Clone() Cloner { } return &NLSLayerGroup{ - layerBase: *clonedBase, + LayerBase: *clonedBase, children: clonedChildren, root: l.root, } @@ -119,33 +119,33 @@ func (l *NLSLayerGroup) IsSketch() bool { if l == nil { return false } - return l.layerBase.IsSketchField + return l.LayerBase.IsSketchField } func (l *NLSLayerGroup) SetIsSketch(isSketch bool) { if l == nil { return } - l.layerBase.IsSketchField = isSketch + l.LayerBase.IsSketchField = isSketch } func (l *NLSLayerGroup) HasSketch() bool { if l == nil { return false } - return l.layerBase.SketchField != nil + return l.LayerBase.SketchField != nil } func (l *NLSLayerGroup) Sketch() *SketchInfo { if l == nil { return nil } - return l.layerBase.SketchField + return l.LayerBase.SketchField } func (l *NLSLayerGroup) SetSketch(sketch *SketchInfo) { if l == nil { return } - l.layerBase.SketchField = sketch + l.LayerBase.SketchField = sketch } diff --git a/server/pkg/nlslayer/group_builder.go b/server/pkg/nlslayer/group_builder.go index 6aff65b797..3a7ee64288 100644 --- a/server/pkg/nlslayer/group_builder.go +++ b/server/pkg/nlslayer/group_builder.go @@ -24,7 +24,7 @@ type NLSLayerGroupBuilder struct { } func NewNLSLayerGroup() *NLSLayerGroupBuilder { - return &NLSLayerGroupBuilder{l: &NLSLayerGroup{layerBase: layerBase{}}} + return &NLSLayerGroupBuilder{l: &NLSLayerGroup{LayerBase: LayerBase{}}} } func (b *NLSLayerGroupBuilder) Build() (*NLSLayerGroup, error) { @@ -42,8 +42,8 @@ func (b *NLSLayerGroupBuilder) MustBuild() *NLSLayerGroup { return group } -func (b *NLSLayerGroupBuilder) base(layer layerBase) *NLSLayerGroupBuilder { - b.l.layerBase = layer +func (b *NLSLayerGroupBuilder) base(layer LayerBase) *NLSLayerGroupBuilder { + b.l.LayerBase = layer return b } diff --git a/server/pkg/nlslayer/nlslayer.go b/server/pkg/nlslayer/nlslayer.go index c937036145..760e69037d 100644 --- a/server/pkg/nlslayer/nlslayer.go +++ b/server/pkg/nlslayer/nlslayer.go @@ -60,7 +60,7 @@ func ToLayerSimpleRef(l *NLSLayer) *NLSLayerSimple { return nil } -type layerBase struct { +type LayerBase struct { IDField ID `msgpack:"IDField"` LayerTypeField LayerType `msgpack:"LayerTypeField"` SceneField SceneID `msgpack:"SceneField"` @@ -72,82 +72,82 @@ type layerBase struct { SketchField *SketchInfo `msgpack:"SketchField"` } -func (l *layerBase) ID() ID { +func (l *LayerBase) ID() ID { return l.IDField } -func (l *layerBase) IDRef() *ID { +func (l *LayerBase) IDRef() *ID { if l == nil { return nil } return l.IDField.Ref() } -func (l *layerBase) LayerType() LayerType { +func (l *LayerBase) LayerType() LayerType { if l == nil { return "" } return l.LayerTypeField } -func (l *layerBase) Scene() SceneID { +func (l *LayerBase) Scene() SceneID { return l.SceneField } -func (l *layerBase) Config() *Config { +func (l *LayerBase) Config() *Config { return l.ConfigField } -func (l *layerBase) Title() string { +func (l *LayerBase) Title() string { if l == nil { return "" } return l.TitleField } -func (l *layerBase) IsVisible() bool { +func (l *LayerBase) IsVisible() bool { if l == nil { return false } return l.VisibleField } -func (l *layerBase) HasInfobox() bool { +func (l *LayerBase) HasInfobox() bool { if l == nil { return false } return l.InfoboxField != nil } -func (l *layerBase) Infobox() *Infobox { +func (l *LayerBase) Infobox() *Infobox { if l == nil { return nil } return l.InfoboxField } -func (l *layerBase) SetVisible(visible bool) { +func (l *LayerBase) SetVisible(visible bool) { if l == nil { return } l.VisibleField = visible } -func (l *layerBase) SetInfobox(infobox *Infobox) { +func (l *LayerBase) SetInfobox(infobox *Infobox) { if l == nil { return } l.InfoboxField = infobox } -func (l *layerBase) Rename(name string) { +func (l *LayerBase) Rename(name string) { if l == nil { return } l.TitleField = name } -func (l *layerBase) UpdateConfig(newConfig *Config) { +func (l *LayerBase) UpdateConfig(newConfig *Config) { if l == nil || newConfig == nil { return } @@ -162,7 +162,7 @@ func (l *layerBase) UpdateConfig(newConfig *Config) { } } -func (l *layerBase) Clone() *layerBase { +func (l *LayerBase) Clone() *LayerBase { if l == nil { return nil } @@ -172,7 +172,7 @@ func (l *layerBase) Clone() *layerBase { clonedConfig = &clonedConfigItem } - cloned := &layerBase{ + cloned := &LayerBase{ IDField: l.IDField, LayerTypeField: l.LayerTypeField, SceneField: l.SceneField, @@ -193,7 +193,7 @@ func (l *layerBase) Clone() *layerBase { return cloned } -func (l *layerBase) Duplicate() NLSLayer { +func (l *LayerBase) Duplicate() NLSLayer { if l == nil { return nil } @@ -203,7 +203,7 @@ func (l *layerBase) Duplicate() NLSLayer { duplicatedConfig = &duplicatedConfigItem } - duplicated := &layerBase{ + duplicated := &LayerBase{ IDField: NewID(), LayerTypeField: l.LayerTypeField, SceneField: l.SceneField, @@ -221,38 +221,38 @@ func (l *layerBase) Duplicate() NLSLayer { duplicated.SketchField = l.SketchField.Clone() } - return &NLSLayerSimple{layerBase: *duplicated} + return &NLSLayerSimple{LayerBase: *duplicated} } -func (l *layerBase) IsSketch() bool { +func (l *LayerBase) IsSketch() bool { if l == nil { return false } return l.IsSketchField } -func (l *layerBase) SetIsSketch(isSketch bool) { +func (l *LayerBase) SetIsSketch(isSketch bool) { if l == nil { return } l.IsSketchField = isSketch } -func (l *layerBase) HasSketch() bool { +func (l *LayerBase) HasSketch() bool { if l == nil { return false } return l.SketchField != nil } -func (l *layerBase) Sketch() *SketchInfo { +func (l *LayerBase) Sketch() *SketchInfo { if l == nil { return nil } return l.SketchField } -func (l *layerBase) SetSketchInfo(sketch *SketchInfo) { +func (l *LayerBase) SetSketchInfo(sketch *SketchInfo) { if l == nil { return } diff --git a/server/pkg/nlslayer/simple.go b/server/pkg/nlslayer/simple.go index 5b0a4a5e28..ea037ad54f 100644 --- a/server/pkg/nlslayer/simple.go +++ b/server/pkg/nlslayer/simple.go @@ -5,26 +5,26 @@ import ( ) type NLSLayerSimple struct { - layerBase + LayerBase } func (l *NLSLayerSimple) ID() ID { - return l.layerBase.ID() + return l.LayerBase.ID() } func (l *NLSLayerSimple) IDRef() *ID { if l == nil { return nil } - return l.layerBase.IDRef() + return l.LayerBase.IDRef() } func (l *NLSLayerSimple) LayerType() LayerType { - return l.layerBase.LayerType() + return l.LayerBase.LayerType() } func (l *NLSLayerSimple) Scene() SceneID { - return l.layerBase.SceneField + return l.LayerBase.SceneField } func (l *NLSLayerSimple) LinkedDataset() *pl.DatasetID { @@ -32,42 +32,42 @@ func (l *NLSLayerSimple) LinkedDataset() *pl.DatasetID { } func (l *NLSLayerSimple) Title() string { - return l.layerBase.Title() + return l.LayerBase.Title() } func (l *NLSLayerSimple) IsVisible() bool { if l == nil { return false } - return l.layerBase.VisibleField + return l.LayerBase.VisibleField } func (l *NLSLayerSimple) HasInfobox() bool { if l == nil { return false } - return l.layerBase.InfoboxField != nil + return l.LayerBase.InfoboxField != nil } func (l *NLSLayerSimple) Infobox() *Infobox { if l == nil { return nil } - return l.layerBase.InfoboxField + return l.LayerBase.InfoboxField } func (l *NLSLayerSimple) SetVisible(visible bool) { if l == nil { return } - l.layerBase.VisibleField = visible + l.LayerBase.VisibleField = visible } func (l *NLSLayerSimple) SetInfobox(infobox *Infobox) { if l == nil { return } - l.layerBase.InfoboxField = infobox + l.LayerBase.InfoboxField = infobox } func (l *NLSLayerSimple) LayerRef() *NLSLayer { @@ -90,10 +90,10 @@ func (l *NLSLayerSimple) Clone() Cloner { return nil } - clonedBase := l.layerBase.Clone() + clonedBase := l.LayerBase.Clone() return &NLSLayerSimple{ - layerBase: *clonedBase, + LayerBase: *clonedBase, } } @@ -101,33 +101,33 @@ func (l *NLSLayerSimple) IsSketch() bool { if l == nil { return false } - return l.layerBase.IsSketchField + return l.LayerBase.IsSketchField } func (l *NLSLayerSimple) SetIsSketch(isSketch bool) { if l == nil { return } - l.layerBase.IsSketchField = isSketch + l.LayerBase.IsSketchField = isSketch } func (l *NLSLayerSimple) HasSketch() bool { if l == nil { return false } - return l.layerBase.SketchField != nil + return l.LayerBase.SketchField != nil } func (l *NLSLayerSimple) Sketch() *SketchInfo { if l == nil { return nil } - return l.layerBase.SketchField + return l.LayerBase.SketchField } func (l *NLSLayerSimple) SetSketch(sketch *SketchInfo) { if l == nil { return } - l.layerBase.SketchField = sketch + l.LayerBase.SketchField = sketch } diff --git a/server/pkg/nlslayer/simple_builder.go b/server/pkg/nlslayer/simple_builder.go index b63bb008e1..d52183767d 100644 --- a/server/pkg/nlslayer/simple_builder.go +++ b/server/pkg/nlslayer/simple_builder.go @@ -24,7 +24,7 @@ type NLSLayerSimpleBuilder struct { } func NewNLSLayerSimple() *NLSLayerSimpleBuilder { - return &NLSLayerSimpleBuilder{l: &NLSLayerSimple{layerBase: layerBase{}}} + return &NLSLayerSimpleBuilder{l: &NLSLayerSimple{LayerBase: LayerBase{}}} } func (b *NLSLayerSimpleBuilder) Build() (*NLSLayerSimple, error) { @@ -42,8 +42,8 @@ func (b *NLSLayerSimpleBuilder) MustBuild() *NLSLayerSimple { return Simple } -func (b *NLSLayerSimpleBuilder) base(layer layerBase) *NLSLayerSimpleBuilder { - b.l.layerBase = layer +func (b *NLSLayerSimpleBuilder) base(layer LayerBase) *NLSLayerSimpleBuilder { + b.l.LayerBase = layer return b } From db80f41f72838d190a0b530ed378ffb6708f0df0 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 16:35:02 +0900 Subject: [PATCH 08/19] fix pkg --- server/pkg/nlslayer/group.go | 6 +++++- server/pkg/nlslayer/nlslayer.go | 9 ++++++++- server/pkg/nlslayer/simple.go | 6 +++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/server/pkg/nlslayer/group.go b/server/pkg/nlslayer/group.go index a01358e3d9..e489b0b80d 100644 --- a/server/pkg/nlslayer/group.go +++ b/server/pkg/nlslayer/group.go @@ -102,6 +102,10 @@ func (l *NLSLayerGroup) Clone() Cloner { } clonedBase := l.LayerBase.Clone() + clonedBaseTyped, ok := clonedBase.(*LayerBase) + if !ok { + return nil + } var clonedChildren *IDList if l.children != nil { @@ -109,7 +113,7 @@ func (l *NLSLayerGroup) Clone() Cloner { } return &NLSLayerGroup{ - LayerBase: *clonedBase, + LayerBase: *clonedBaseTyped, children: clonedChildren, root: l.root, } diff --git a/server/pkg/nlslayer/nlslayer.go b/server/pkg/nlslayer/nlslayer.go index 760e69037d..ecb3ebf2f4 100644 --- a/server/pkg/nlslayer/nlslayer.go +++ b/server/pkg/nlslayer/nlslayer.go @@ -162,7 +162,7 @@ func (l *LayerBase) UpdateConfig(newConfig *Config) { } } -func (l *LayerBase) Clone() *LayerBase { +func (l *LayerBase) Clone() Cloner { if l == nil { return nil } @@ -252,6 +252,13 @@ func (l *LayerBase) Sketch() *SketchInfo { return l.SketchField } +func (l *LayerBase) SetSketch(sketch *SketchInfo) { + if l == nil { + return + } + l.SketchField = sketch +} + func (l *LayerBase) SetSketchInfo(sketch *SketchInfo) { if l == nil { return diff --git a/server/pkg/nlslayer/simple.go b/server/pkg/nlslayer/simple.go index ea037ad54f..23f7777404 100644 --- a/server/pkg/nlslayer/simple.go +++ b/server/pkg/nlslayer/simple.go @@ -91,9 +91,13 @@ func (l *NLSLayerSimple) Clone() Cloner { } clonedBase := l.LayerBase.Clone() + clonedBaseTyped, ok := clonedBase.(*LayerBase) + if !ok { + return nil + } return &NLSLayerSimple{ - LayerBase: *clonedBase, + LayerBase: *clonedBaseTyped, } } From 1ce9dec679cad238a005824a9ca2474cf1e84d11 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 18:07:26 +0900 Subject: [PATCH 09/19] fix pkg --- server/pkg/nlslayer/feature.go | 32 ++++++------ server/pkg/nlslayer/feature_collection.go | 30 ++++++------ server/pkg/nlslayer/geometry.go | 60 +++++++++++------------ server/pkg/nlslayer/sketch_info.go | 18 +++---- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/server/pkg/nlslayer/feature.go b/server/pkg/nlslayer/feature.go index ed742d5f13..9ad8049c10 100644 --- a/server/pkg/nlslayer/feature.go +++ b/server/pkg/nlslayer/feature.go @@ -1,25 +1,25 @@ package nlslayer type Feature struct { - id FeatureID - featureType string - geometry Geometry - properties *map[string]any + IDField FeatureID `msgpack:"IDField"` + FeatureTypeField string `msgpack:"FeatureTypeField"` + GeometryField Geometry `msgpack:"GeometryField"` + PropertiesField *map[string]any `msgpack:"PropertiesField"` } func NewFeatureWithNewId(featureType string, geometry Geometry) (*Feature, error) { return &Feature{ - id: NewFeatureID(), - featureType: featureType, - geometry: geometry, + IDField: NewFeatureID(), + FeatureTypeField: featureType, + GeometryField: geometry, }, nil } func NewFeature(id FeatureID, featureType string, geometry Geometry) (*Feature, error) { return &Feature{ - id: id, - featureType: featureType, - geometry: geometry, + IDField: id, + FeatureTypeField: featureType, + GeometryField: geometry, }, nil } @@ -27,29 +27,29 @@ func (f *Feature) ID() FeatureID { if f == nil { return FeatureID{} } - return f.id + return f.IDField } func (f *Feature) FeatureType() string { if f == nil { return "" } - return f.featureType + return f.FeatureTypeField } func (f *Feature) Geometry() Geometry { if f == nil { return nil } - return f.geometry + return f.GeometryField } func (f *Feature) Properties() *map[string]any { - return f.properties + return f.PropertiesField } func (f *Feature) UpdateGeometry(newGeometry Geometry) { - f.geometry = newGeometry + f.GeometryField = newGeometry } func (f *Feature) UpdateProperties(newProperty *map[string]any) { @@ -62,5 +62,5 @@ func (f *Feature) UpdateProperties(newProperty *map[string]any) { clonedProperties[key] = value } - f.properties = &clonedProperties + f.PropertiesField = &clonedProperties } diff --git a/server/pkg/nlslayer/feature_collection.go b/server/pkg/nlslayer/feature_collection.go index bde588c3cf..5bddf2e54f 100644 --- a/server/pkg/nlslayer/feature_collection.go +++ b/server/pkg/nlslayer/feature_collection.go @@ -5,44 +5,44 @@ import ( ) type FeatureCollection struct { - featureCollectionType string - features []Feature + FeatureCollectionTypeField string `msgpack:"FeatureCollectionTypeField"` + FeaturesField []Feature `msgpack:"FeaturesField"` } func NewFeatureCollection(featureCollectionType string, features []Feature) *FeatureCollection { return &FeatureCollection{ - featureCollectionType: featureCollectionType, - features: features, + FeatureCollectionTypeField: featureCollectionType, + FeaturesField: features, } } func (fc *FeatureCollection) FeatureCollectionType() string { - return fc.featureCollectionType + return fc.FeatureCollectionTypeField } func (fc *FeatureCollection) Features() []Feature { if fc == nil { return nil } - return append([]Feature{}, fc.features...) + return append([]Feature{}, fc.FeaturesField...) } func (fc *FeatureCollection) AddFeature(feature Feature) { if fc == nil { return } - fc.features = append(fc.features, feature) + fc.FeaturesField = append(fc.FeaturesField, feature) } func (fc *FeatureCollection) UpdateFeature(id FeatureID, geometry Geometry, properties map[string]any) (Feature, error) { - for i, f := range fc.features { + for i, f := range fc.FeaturesField { if f.ID() == id { updatedFeature, err := NewFeature(id, f.FeatureType(), geometry) if err != nil { return Feature{}, err } updatedFeature.UpdateProperties(&properties) - fc.features[i] = *updatedFeature + fc.FeaturesField[i] = *updatedFeature return *updatedFeature, nil } } @@ -50,10 +50,10 @@ func (fc *FeatureCollection) UpdateFeature(id FeatureID, geometry Geometry, prop } func (fc *FeatureCollection) UpdateFeatureGeometry(id FeatureID, geometry Geometry) (Feature, error) { - for i, f := range fc.features { + for i, f := range fc.FeaturesField { if f.ID() == id { f.UpdateGeometry(geometry) - fc.features[i] = f + fc.FeaturesField[i] = f return f, nil } } @@ -61,10 +61,10 @@ func (fc *FeatureCollection) UpdateFeatureGeometry(id FeatureID, geometry Geomet } func (fc *FeatureCollection) UpdateFeatureProperty(id FeatureID, properties map[string]any) (Feature, error) { - for i, f := range fc.features { + for i, f := range fc.FeaturesField { if f.ID() == id { f.UpdateProperties(&properties) - fc.features[i] = f + fc.FeaturesField[i] = f return f, nil } } @@ -76,9 +76,9 @@ func (fc *FeatureCollection) RemoveFeature(id FeatureID) error { return errors.New("feature collection is nil") } - for i, feature := range fc.features { + for i, feature := range fc.FeaturesField { if feature.ID() == id { - fc.features = append(fc.features[:i], fc.features[i+1:]...) + fc.FeaturesField = append(fc.FeaturesField[:i], fc.FeaturesField[i+1:]...) return nil } } diff --git a/server/pkg/nlslayer/geometry.go b/server/pkg/nlslayer/geometry.go index f739200d9f..cc5752676d 100644 --- a/server/pkg/nlslayer/geometry.go +++ b/server/pkg/nlslayer/geometry.go @@ -8,106 +8,106 @@ import ( type Geometry interface{} type Point struct { - pointType string - coordinates []float64 + PointTypeField string `msgpack:"PointTypeField"` + CoordinatesField []float64 `msgpack:"CoordinatesField"` } type LineString struct { - lineStringType string - coordinates [][]float64 + LineStringTypeField string `msgpack:"LineStringTypeField"` + CoordinatesField [][]float64 `msgpack:"CoordinatesField"` } type Polygon struct { - polygonType string - coordinates [][][]float64 + PolygonTypeField string `msgpack:"PolygonTypeField"` + CoordinatesField [][][]float64 `msgpack:"CoordinatesField"` } type MultiPolygon struct { - multiPolygonType string - coordinates [][][][]float64 + MultiPolygonTypeField string `msgpack:"MultiPolygonTypeField"` + CoordinatesField [][][][]float64 `msgpack:"CoordinatesField"` } type GeometryCollection struct { - geometryCollectionType string - geometries []Geometry + GeometryCollectionTypeField string `msgpack:"GeometryCollectionTypeField"` + GeometriesField []Geometry `msgpack:"GeometriesField"` } func NewPoint(pointType string, coordinates []float64) *Point { return &Point{ - pointType: pointType, - coordinates: coordinates, + PointTypeField: pointType, + CoordinatesField: coordinates, } } func (p *Point) PointType() string { - return p.pointType + return p.PointTypeField } func (p *Point) Coordinates() []float64 { - return append([]float64{}, p.coordinates...) + return append([]float64{}, p.CoordinatesField...) } func NewLineString(lineStringType string, coordinates [][]float64) *LineString { return &LineString{ - lineStringType: lineStringType, - coordinates: coordinates, + LineStringTypeField: lineStringType, + CoordinatesField: coordinates, } } func (l *LineString) LineStringType() string { - return l.lineStringType + return l.LineStringTypeField } func (l *LineString) Coordinates() [][]float64 { - return append([][]float64{}, l.coordinates...) + return append([][]float64{}, l.CoordinatesField...) } func NewPolygon(polygonType string, coordinates [][][]float64) *Polygon { return &Polygon{ - polygonType: polygonType, - coordinates: coordinates, + PolygonTypeField: polygonType, + CoordinatesField: coordinates, } } func (p *Polygon) PolygonType() string { - return p.polygonType + return p.PolygonTypeField } func (p *Polygon) Coordinates() [][][]float64 { - return append([][][]float64{}, p.coordinates...) + return append([][][]float64{}, p.CoordinatesField...) } func NewMultiPolygon(multiPolygonType string, coordinates [][][][]float64) *MultiPolygon { return &MultiPolygon{ - multiPolygonType: multiPolygonType, - coordinates: coordinates, + MultiPolygonTypeField: multiPolygonType, + CoordinatesField: coordinates, } } func (m *MultiPolygon) MultiPolygonType() string { - return m.multiPolygonType + return m.MultiPolygonTypeField } func (m *MultiPolygon) Coordinates() [][][][]float64 { - return append([][][][]float64{}, m.coordinates...) + return append([][][][]float64{}, m.CoordinatesField...) } func NewGeometryCollection(geometryCollectionType string, geometries []Geometry) *GeometryCollection { return &GeometryCollection{ - geometryCollectionType: geometryCollectionType, - geometries: geometries, + GeometryCollectionTypeField: geometryCollectionType, + GeometriesField: geometries, } } func (g *GeometryCollection) GeometryCollectionType() string { - return g.geometryCollectionType + return g.GeometryCollectionTypeField } func (g *GeometryCollection) Geometries() []Geometry { if g == nil { return nil } - return append([]Geometry{}, g.geometries...) + return append([]Geometry{}, g.GeometriesField...) } func NewGeometryFromMap(data map[string]any) (Geometry, error) { diff --git a/server/pkg/nlslayer/sketch_info.go b/server/pkg/nlslayer/sketch_info.go index 81110e26f7..d2024d56d2 100644 --- a/server/pkg/nlslayer/sketch_info.go +++ b/server/pkg/nlslayer/sketch_info.go @@ -1,27 +1,27 @@ package nlslayer type SketchInfo struct { - customPropertySchema *map[string]any - featureCollection *FeatureCollection + CustomPropertySchemaField *map[string]any `msgpack:"CustomPropertySchemaField"` + FeatureCollectionField *FeatureCollection `msgpack:"FeatureCollectionField"` } func NewSketchInfo(customPropertySchema *map[string]any, featureCollection *FeatureCollection) *SketchInfo { return &SketchInfo{ - customPropertySchema: customPropertySchema, - featureCollection: featureCollection, + CustomPropertySchemaField: customPropertySchema, + FeatureCollectionField: featureCollection, } } func (s *SketchInfo) CustomPropertySchema() *map[string]any { - return s.customPropertySchema + return s.CustomPropertySchemaField } func (s *SketchInfo) FeatureCollection() *FeatureCollection { - return s.featureCollection + return s.FeatureCollectionField } func (s *SketchInfo) SetCustomPropertySchema(schema *map[string]any) { - s.customPropertySchema = schema + s.CustomPropertySchemaField = schema } func (s *SketchInfo) Clone() *SketchInfo { @@ -30,7 +30,7 @@ func (s *SketchInfo) Clone() *SketchInfo { } return &SketchInfo{ - customPropertySchema: s.customPropertySchema, - featureCollection: s.featureCollection, + CustomPropertySchemaField: s.CustomPropertySchemaField, + FeatureCollectionField: s.FeatureCollectionField, } } From 99f1c85106eb9edba3555eb44aa0db6d95bbad06 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 18:10:48 +0900 Subject: [PATCH 10/19] nlslayer --- .../internal/usecase/interactor/nlslayer.go | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/server/internal/usecase/interactor/nlslayer.go b/server/internal/usecase/interactor/nlslayer.go index 021c6c1938..bd0182c9a3 100644 --- a/server/internal/usecase/interactor/nlslayer.go +++ b/server/internal/usecase/interactor/nlslayer.go @@ -4,7 +4,9 @@ import ( "context" "errors" + "github.com/go-redis/redis/v8" "github.com/reearth/reearth/server/internal/usecase" + "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interfaces" "github.com/reearth/reearth/server/internal/usecase/repo" "github.com/reearth/reearth/server/pkg/builtin" @@ -15,6 +17,7 @@ import ( "github.com/reearth/reearth/server/pkg/property" "github.com/reearth/reearthx/rerror" "github.com/reearth/reearthx/usecasex" + "github.com/vmihailenco/msgpack/v5" ) type NLSLayer struct { @@ -25,9 +28,10 @@ type NLSLayer struct { propertyRepo repo.Property pluginRepo repo.Plugin transaction usecasex.Transaction + redis gateway.RedisGateway } -func NewNLSLayer(r *repo.Container) interfaces.NLSLayer { +func NewNLSLayer(r *repo.Container, redis gateway.RedisGateway) interfaces.NLSLayer { return &NLSLayer{ commonSceneLock: commonSceneLock{sceneLockRepo: r.SceneLock}, nlslayerRepo: r.NLSLayer, @@ -35,6 +39,7 @@ func NewNLSLayer(r *repo.Container) interfaces.NLSLayer { propertyRepo: r.Property, pluginRepo: r.Plugin, transaction: r.Transaction, + redis: redis, } } @@ -102,6 +107,11 @@ func (i *NLSLayer) AddLayerSimple(ctx context.Context, inp interfaces.AddNLSLaye return nil, err } + err = i.setNLSLayerToCache(ctx, layerSimple.ID(), layerSimple) + if err != nil { + return nil, err + } + tx.Commit() return layerSimple, nil } @@ -139,15 +149,24 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec } }() - l, err := i.nlslayerRepo.FindByID(ctx, lid) + var layer nlslayer.NLSLayer + layer, err = i.getNLSLayerFromCache(ctx, lid) if err != nil { return lid, nil, err } - if err := i.CanWriteScene(l.Scene(), operator); err != nil { + + if layer == nil { + layer, err = i.nlslayerRepo.FindByID(ctx, lid) + if err != nil { + return lid, nil, err + } + } + + if err := i.CanWriteScene(layer.Scene(), operator); err != nil { return lid, nil, err } - if err := i.CheckSceneLock(ctx, l.Scene()); err != nil { + if err := i.CheckSceneLock(ctx, layer.Scene()); err != nil { return lid, nil, err } @@ -156,7 +175,7 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec return lid, nil, err } if parentLayer != nil { - if l.Scene() != parentLayer.Scene() { + if layer.Scene() != parentLayer.Scene() { return lid, nil, errors.New("invalid layer") } } @@ -171,17 +190,25 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec return lid, nil, err } } - layers, err := i.fetchAllChildren(ctx, l) + layers, err := i.fetchAllChildren(ctx, layer) if err != nil { return lid, nil, err } - layers = append(layers, l.ID()) + layers = append(layers, layer.ID()) err = i.nlslayerRepo.RemoveAll(ctx, layers) if err != nil { return lid, nil, err } tx.Commit() + + for _, l := range layers { + err = i.removeNLSLayerFromCache(ctx, l) + if err != nil { + return l, nil, err + } + } + return lid, parentLayer, nil } @@ -198,10 +225,19 @@ func (i *NLSLayer) Update(ctx context.Context, inp interfaces.UpdateNLSLayerInpu } }() - layer, err := i.nlslayerRepo.FindByID(ctx, inp.LayerID) + var layer nlslayer.NLSLayer + layer, err = i.getNLSLayerFromCache(ctx, inp.LayerID) if err != nil { return nil, err } + + if layer == nil { + layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID) + if err != nil { + return nil, err + } + } + if err := i.CanWriteScene(layer.Scene(), operator); err != nil { return nil, err } @@ -224,6 +260,12 @@ func (i *NLSLayer) Update(ctx context.Context, inp interfaces.UpdateNLSLayerInpu } tx.Commit() + + err = i.setNLSLayerToCache(ctx, layer.ID(), layer) + if err != nil { + return nil, err + } + return layer, nil } @@ -732,3 +774,37 @@ func (i *NLSLayer) DeleteGeoJSONFeature(ctx context.Context, inp interfaces.Dele tx.Commit() return inp.FeatureID, nil } + +func (i *NLSLayer) getNLSLayerFromCache(ctx context.Context, lid id.NLSLayerID) (nlslayer.NLSLayer, error) { + cacheKey := nlslayer.NLSLayerCacheKey(lid) + val, err := i.redis.GetValue(ctx, cacheKey) + if err != nil { + if err == redis.Nil { + return nil, nil + } + + return nil, err + } + + var l *nlslayer.NLSLayerSimple + if err := msgpack.Unmarshal([]byte(val), &l); err != nil { + return nil, err + } + + return l, nil +} + +func (i *NLSLayer) setNLSLayerToCache(ctx context.Context, lid id.NLSLayerID, layer nlslayer.NLSLayer) error { + cacheKey := nlslayer.NLSLayerCacheKey(lid) + data, err := msgpack.Marshal(layer) + if err != nil { + return err + } + + return i.redis.SetValue(ctx, cacheKey, data) +} + +func (i *NLSLayer) removeNLSLayerFromCache(ctx context.Context, lid id.NLSLayerID) error { + cacheKey := nlslayer.NLSLayerCacheKey(lid) + return i.redis.RemoveValue(ctx, cacheKey) +} From 864d42c7608febb6ee9e81608b05f8b3a4c68cdd Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 18:22:37 +0900 Subject: [PATCH 11/19] fix pkg --- server/pkg/nlslayer/geometry_test.go | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/server/pkg/nlslayer/geometry_test.go b/server/pkg/nlslayer/geometry_test.go index d2caab0dbd..2d44b7904f 100644 --- a/server/pkg/nlslayer/geometry_test.go +++ b/server/pkg/nlslayer/geometry_test.go @@ -59,8 +59,8 @@ func TestNewGeometryFromMap(t *testing.T) { "coordinates": []interface{}{1.0, 2.0}, }, want: &Point{ - pointType: "Point", - coordinates: []float64{1.0, 2.0}, + PointTypeField: "Point", + CoordinatesField: []float64{1.0, 2.0}, }, wantErr: false, }, @@ -74,8 +74,8 @@ func TestNewGeometryFromMap(t *testing.T) { }, }, want: &LineString{ - lineStringType: "LineString", - coordinates: [][]float64{ + LineStringTypeField: "LineString", + CoordinatesField: [][]float64{ {1.0, 2.0}, {3.0, 4.0}, }, @@ -96,8 +96,8 @@ func TestNewGeometryFromMap(t *testing.T) { }, }, want: &Polygon{ - polygonType: "Polygon", - coordinates: [][][]float64{{ + PolygonTypeField: "Polygon", + CoordinatesField: [][][]float64{{ {1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}, @@ -122,8 +122,8 @@ func TestNewGeometryFromMap(t *testing.T) { }, }, want: &MultiPolygon{ - multiPolygonType: "MultiPolygon", - coordinates: [][][][]float64{{{ + MultiPolygonTypeField: "MultiPolygon", + CoordinatesField: [][][][]float64{{{ {1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}, @@ -175,22 +175,22 @@ func TestNewGeometryFromMap(t *testing.T) { }, }, want: &GeometryCollection{ - geometryCollectionType: "GeometryCollection", - geometries: []Geometry{ + GeometryCollectionTypeField: "GeometryCollection", + GeometriesField: []Geometry{ &Point{ - pointType: "Point", - coordinates: []float64{1.0, 2.0}, + PointTypeField: "Point", + CoordinatesField: []float64{1.0, 2.0}, }, &LineString{ - lineStringType: "LineString", - coordinates: [][]float64{ + LineStringTypeField: "LineString", + CoordinatesField: [][]float64{ {1.0, 2.0}, {3.0, 4.0}, }, }, &Polygon{ - polygonType: "Polygon", - coordinates: [][][]float64{{ + PolygonTypeField: "Polygon", + CoordinatesField: [][][]float64{{ {1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}, @@ -198,8 +198,8 @@ func TestNewGeometryFromMap(t *testing.T) { }}, }, &MultiPolygon{ - multiPolygonType: "MultiPolygon", - coordinates: [][][][]float64{{{ + MultiPolygonTypeField: "MultiPolygon", + CoordinatesField: [][][][]float64{{{ {1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}, From 228e34b3f9c2eda2c3c1ce92a4d4776508cec701 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 18:23:03 +0900 Subject: [PATCH 12/19] nlslayer test --- server/internal/usecase/interactor/nlslayer_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/internal/usecase/interactor/nlslayer_test.go b/server/internal/usecase/interactor/nlslayer_test.go index d914a74742..edfce6344b 100644 --- a/server/internal/usecase/interactor/nlslayer_test.go +++ b/server/internal/usecase/interactor/nlslayer_test.go @@ -20,7 +20,7 @@ func TestAddCustomProperties(t *testing.T) { db := memory.New() scene, _ := scene.New().NewID().Workspace(accountdomain.NewWorkspaceID()).Project(id.NewProjectID()).RootLayer(id.NewLayerID()).Build() _ = db.Scene.Save(ctx, scene) - il := NewNLSLayer(db) + il := NewNLSLayer(db, nil) l, _ := nlslayer.NewNLSLayerSimple().NewID().Scene(scene.ID()).Build() _ = db.NLSLayer.Save(ctx, l) @@ -52,7 +52,7 @@ func TestAddGeoJSONFeature(t *testing.T) { db := memory.New() scene, _ := scene.New().NewID().Workspace(accountdomain.NewWorkspaceID()).Project(id.NewProjectID()).RootLayer(id.NewLayerID()).Build() _ = db.Scene.Save(ctx, scene) - il := NewNLSLayer(db) + il := NewNLSLayer(db, nil) l, _ := nlslayer.NewNLSLayerSimple().NewID().Scene(scene.ID()).Build() _ = db.NLSLayer.Save(ctx, l) @@ -105,7 +105,7 @@ func TestUpdateGeoJSONFeature(t *testing.T) { db := memory.New() scene, _ := scene.New().NewID().Workspace(accountdomain.NewWorkspaceID()).Project(id.NewProjectID()).RootLayer(id.NewLayerID()).Build() _ = db.Scene.Save(ctx, scene) - il := NewNLSLayer(db) + il := NewNLSLayer(db, nil) l, _ := nlslayer.NewNLSLayerSimple().NewID().Scene(scene.ID()).Build() _ = db.NLSLayer.Save(ctx, l) @@ -180,7 +180,7 @@ func TestDeleteGeoJSONFeature(t *testing.T) { db := memory.New() scene, _ := scene.New().NewID().Workspace(accountdomain.NewWorkspaceID()).Project(id.NewProjectID()).RootLayer(id.NewLayerID()).Build() _ = db.Scene.Save(ctx, scene) - il := NewNLSLayer(db) + il := NewNLSLayer(db, nil) l, _ := nlslayer.NewNLSLayerSimple().NewID().Scene(scene.ID()).Build() _ = db.NLSLayer.Save(ctx, l) From 0daa45940ab4fa65167b094125ce694873694814 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Sun, 14 Apr 2024 18:23:26 +0900 Subject: [PATCH 13/19] e2e --- server/e2e/gql_featureCollection_test.go | 8 ++++++++ server/e2e/gql_nlslayer_test.go | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/server/e2e/gql_featureCollection_test.go b/server/e2e/gql_featureCollection_test.go index f75d429bb2..dcfb8c847a 100644 --- a/server/e2e/gql_featureCollection_test.go +++ b/server/e2e/gql_featureCollection_test.go @@ -4,6 +4,7 @@ import ( "net/http" "testing" + "github.com/alicebob/miniredis/v2" "github.com/gavv/httpexpect/v2" "github.com/reearth/reearth/server/internal/app/config" ) @@ -197,11 +198,18 @@ func deleteGeoJSONFeature( } func TestFeatureCollectionCRUD(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, true, baseSeeder) pId := createProject(e) diff --git a/server/e2e/gql_nlslayer_test.go b/server/e2e/gql_nlslayer_test.go index 3c234744e4..b9053735ba 100644 --- a/server/e2e/gql_nlslayer_test.go +++ b/server/e2e/gql_nlslayer_test.go @@ -4,6 +4,7 @@ import ( "net/http" "testing" + "github.com/alicebob/miniredis/v2" "github.com/gavv/httpexpect/v2" "github.com/reearth/reearth/server/internal/app/config" "github.com/samber/lo" @@ -300,11 +301,18 @@ func fetchSceneForNewLayers(e *httpexpect.Expect, sID string) (GraphQLRequest, * } func TestNLSLayerCRUD(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, true, baseSeeder) pId := createProject(e) @@ -653,12 +661,18 @@ func moveInfoboxBlock(e *httpexpect.Expect, layerId, infoboxBlockId string, inde } func TestInfoboxBlocksCRUD(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, true, baseSeeder) pId := createProject(e) @@ -755,11 +769,18 @@ func addCustomProperties( } func TestCustomProperties(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, + RedisHost: mr.Addr(), }, true, baseSeeder) pId := createProject(e) From ddbef548f1656ba00260184251c99b939555af55 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Mon, 15 Apr 2024 20:15:35 +0900 Subject: [PATCH 14/19] nlslayer duplicate --- server/internal/usecase/interactor/nlslayer.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/server/internal/usecase/interactor/nlslayer.go b/server/internal/usecase/interactor/nlslayer.go index bd0182c9a3..18ef58007d 100644 --- a/server/internal/usecase/interactor/nlslayer.go +++ b/server/internal/usecase/interactor/nlslayer.go @@ -564,10 +564,19 @@ func (i *NLSLayer) Duplicate(ctx context.Context, lid id.NLSLayerID, operator *u } }() - layer, err := i.nlslayerRepo.FindByID(ctx, lid) + var layer nlslayer.NLSLayer + layer, err = i.getNLSLayerFromCache(ctx, lid) if err != nil { return nil, err } + + if layer == nil { + layer, err = i.nlslayerRepo.FindByID(ctx, lid) + if err != nil { + return nil, err + } + } + if err := i.CanWriteScene(layer.Scene(), operator); err != nil { return nil, err } @@ -580,6 +589,12 @@ func (i *NLSLayer) Duplicate(ctx context.Context, lid id.NLSLayerID, operator *u } tx.Commit() + + err = i.setNLSLayerToCache(ctx, duplicatedLayer.ID(), duplicatedLayer) + if err != nil { + return nil, err + } + return duplicatedLayer, nil } From 1d540113f056fa0dc0095f095091ff980d4d0569 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 20:35:19 +0900 Subject: [PATCH 15/19] Refactoring nlslayer --- .../internal/usecase/interactor/nlslayer.go | 50 +++---------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/server/internal/usecase/interactor/nlslayer.go b/server/internal/usecase/interactor/nlslayer.go index 18ef58007d..c3837513be 100644 --- a/server/internal/usecase/interactor/nlslayer.go +++ b/server/internal/usecase/interactor/nlslayer.go @@ -4,7 +4,6 @@ import ( "context" "errors" - "github.com/go-redis/redis/v8" "github.com/reearth/reearth/server/internal/usecase" "github.com/reearth/reearth/server/internal/usecase/gateway" "github.com/reearth/reearth/server/internal/usecase/interfaces" @@ -17,7 +16,6 @@ import ( "github.com/reearth/reearth/server/pkg/property" "github.com/reearth/reearthx/rerror" "github.com/reearth/reearthx/usecasex" - "github.com/vmihailenco/msgpack/v5" ) type NLSLayer struct { @@ -107,7 +105,7 @@ func (i *NLSLayer) AddLayerSimple(ctx context.Context, inp interfaces.AddNLSLaye return nil, err } - err = i.setNLSLayerToCache(ctx, layerSimple.ID(), layerSimple) + err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layerSimple.ID()), layerSimple) if err != nil { return nil, err } @@ -150,7 +148,7 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec }() var layer nlslayer.NLSLayer - layer, err = i.getNLSLayerFromCache(ctx, lid) + layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) if err != nil { return lid, nil, err } @@ -203,7 +201,7 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec tx.Commit() for _, l := range layers { - err = i.removeNLSLayerFromCache(ctx, l) + err = deleteFromCache(ctx, i.redis, nlslayer.NLSLayerCacheKey(l)) if err != nil { return l, nil, err } @@ -226,7 +224,7 @@ func (i *NLSLayer) Update(ctx context.Context, inp interfaces.UpdateNLSLayerInpu }() var layer nlslayer.NLSLayer - layer, err = i.getNLSLayerFromCache(ctx, inp.LayerID) + layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID)) if err != nil { return nil, err } @@ -261,7 +259,7 @@ func (i *NLSLayer) Update(ctx context.Context, inp interfaces.UpdateNLSLayerInpu tx.Commit() - err = i.setNLSLayerToCache(ctx, layer.ID(), layer) + err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layer.ID()), layer) if err != nil { return nil, err } @@ -565,7 +563,7 @@ func (i *NLSLayer) Duplicate(ctx context.Context, lid id.NLSLayerID, operator *u }() var layer nlslayer.NLSLayer - layer, err = i.getNLSLayerFromCache(ctx, lid) + layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) if err != nil { return nil, err } @@ -590,7 +588,7 @@ func (i *NLSLayer) Duplicate(ctx context.Context, lid id.NLSLayerID, operator *u tx.Commit() - err = i.setNLSLayerToCache(ctx, duplicatedLayer.ID(), duplicatedLayer) + err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(duplicatedLayer.ID()), duplicatedLayer) if err != nil { return nil, err } @@ -789,37 +787,3 @@ func (i *NLSLayer) DeleteGeoJSONFeature(ctx context.Context, inp interfaces.Dele tx.Commit() return inp.FeatureID, nil } - -func (i *NLSLayer) getNLSLayerFromCache(ctx context.Context, lid id.NLSLayerID) (nlslayer.NLSLayer, error) { - cacheKey := nlslayer.NLSLayerCacheKey(lid) - val, err := i.redis.GetValue(ctx, cacheKey) - if err != nil { - if err == redis.Nil { - return nil, nil - } - - return nil, err - } - - var l *nlslayer.NLSLayerSimple - if err := msgpack.Unmarshal([]byte(val), &l); err != nil { - return nil, err - } - - return l, nil -} - -func (i *NLSLayer) setNLSLayerToCache(ctx context.Context, lid id.NLSLayerID, layer nlslayer.NLSLayer) error { - cacheKey := nlslayer.NLSLayerCacheKey(lid) - data, err := msgpack.Marshal(layer) - if err != nil { - return err - } - - return i.redis.SetValue(ctx, cacheKey, data) -} - -func (i *NLSLayer) removeNLSLayerFromCache(ctx context.Context, lid id.NLSLayerID) error { - cacheKey := nlslayer.NLSLayerCacheKey(lid) - return i.redis.RemoveValue(ctx, cacheKey) -} From 8fac3af0fc3065b024f140beadc94405a4ab0f68 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 20:39:29 +0900 Subject: [PATCH 16/19] fix e2e --- server/e2e/gql_featureCollection_test.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/server/e2e/gql_featureCollection_test.go b/server/e2e/gql_featureCollection_test.go index dcfb8c847a..1a89bd88a2 100644 --- a/server/e2e/gql_featureCollection_test.go +++ b/server/e2e/gql_featureCollection_test.go @@ -197,19 +197,23 @@ func deleteGeoJSONFeature( return requestBody, res, fId } -func TestFeatureCollectionCRUD(t *testing.T) { - mr, err := miniredis.Run() - if err != nil { - t.Fatal(err) +func featureCollectionCRUD(t *testing.T, isUseRedis bool) { + redisAddress := "" + if isUseRedis { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + redisAddress = mr.Addr() } - defer mr.Close() e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, - RedisHost: mr.Addr(), + RedisHost: redisAddress, }, true, baseSeeder) pId := createProject(e) @@ -514,3 +518,11 @@ func TestFeatureCollectionCRUD(t *testing.T) { Value("features").Array(). Length().Equal(0) } + +func TestFeatureCollectionCRUD(t *testing.T) { + featureCollectionCRUD(t, false) +} + +func TestFeatureCollectionCRUDWithRedis(t *testing.T) { + featureCollectionCRUD(t, true) +} From 66c7eec5b994bd800893b27ae2679a766bd216b8 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 21:06:11 +0900 Subject: [PATCH 17/19] Refactoring nlslayer --- server/internal/usecase/interactor/nlslayer.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/server/internal/usecase/interactor/nlslayer.go b/server/internal/usecase/interactor/nlslayer.go index c3837513be..c7e05a0384 100644 --- a/server/internal/usecase/interactor/nlslayer.go +++ b/server/internal/usecase/interactor/nlslayer.go @@ -148,16 +148,18 @@ func (i *NLSLayer) Remove(ctx context.Context, lid id.NLSLayerID, operator *usec }() var layer nlslayer.NLSLayer - layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) + layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) if err != nil { return lid, nil, err } - if layer == nil { + if layerSimple == nil { layer, err = i.nlslayerRepo.FindByID(ctx, lid) if err != nil { return lid, nil, err } + } else { + layer = layerSimple } if err := i.CanWriteScene(layer.Scene(), operator); err != nil { @@ -224,16 +226,18 @@ func (i *NLSLayer) Update(ctx context.Context, inp interfaces.UpdateNLSLayerInpu }() var layer nlslayer.NLSLayer - layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID)) + layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID)) if err != nil { return nil, err } - if layer == nil { + if layerSimple == nil { layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID) if err != nil { return nil, err } + } else { + layer = layerSimple } if err := i.CanWriteScene(layer.Scene(), operator); err != nil { @@ -563,16 +567,18 @@ func (i *NLSLayer) Duplicate(ctx context.Context, lid id.NLSLayerID, operator *u }() var layer nlslayer.NLSLayer - layer, err = getFromCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) + layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(lid)) if err != nil { return nil, err } - if layer == nil { + if layerSimple == nil { layer, err = i.nlslayerRepo.FindByID(ctx, lid) if err != nil { return nil, err } + } else { + layer = layerSimple } if err := i.CanWriteScene(layer.Scene(), operator); err != nil { From df52e254752ab6ddad866d0654629bd8690703ed Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 21:06:17 +0900 Subject: [PATCH 18/19] fix e2e --- server/e2e/gql_nlslayer_test.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/server/e2e/gql_nlslayer_test.go b/server/e2e/gql_nlslayer_test.go index b9053735ba..1232d5b93e 100644 --- a/server/e2e/gql_nlslayer_test.go +++ b/server/e2e/gql_nlslayer_test.go @@ -300,19 +300,23 @@ func fetchSceneForNewLayers(e *httpexpect.Expect, sID string) (GraphQLRequest, * return fetchSceneRequestBody, res } -func TestNLSLayerCRUD(t *testing.T) { - mr, err := miniredis.Run() - if err != nil { - t.Fatal(err) +func nlsLayerCRUD(t *testing.T, isUseRedis bool) { + redisAddress := "" + if isUseRedis { + mr, err := miniredis.Run() + if err != nil { + t.Fatal(err) + } + defer mr.Close() + redisAddress = mr.Addr() } - defer mr.Close() e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, - RedisHost: mr.Addr(), + RedisHost: redisAddress, }, true, baseSeeder) pId := createProject(e) @@ -427,6 +431,14 @@ func TestNLSLayerCRUD(t *testing.T) { Length().Equal(0) } +func TestNLSLayerCRUD(t *testing.T) { + nlsLayerCRUD(t, false) +} + +func TestNLSLayerCRUDWithRedis(t *testing.T) { + nlsLayerCRUD(t, true) +} + func createInfobox(e *httpexpect.Expect, layerId string) (GraphQLRequest, *httpexpect.Value, string) { requestBody := GraphQLRequest{ OperationName: "CreateNLSInfobox", From 15875d569827b8665325030b787650c3ddca2a58 Mon Sep 17 00:00:00 2001 From: akiyatomohiro Date: Thu, 18 Apr 2024 21:17:06 +0900 Subject: [PATCH 19/19] fix nlslayer --- server/internal/usecase/interactor/nlslayer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/internal/usecase/interactor/nlslayer.go b/server/internal/usecase/interactor/nlslayer.go index c7e05a0384..3b4969161c 100644 --- a/server/internal/usecase/interactor/nlslayer.go +++ b/server/internal/usecase/interactor/nlslayer.go @@ -105,12 +105,13 @@ func (i *NLSLayer) AddLayerSimple(ctx context.Context, inp interfaces.AddNLSLaye return nil, err } + tx.Commit() + err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layerSimple.ID()), layerSimple) if err != nil { return nil, err } - tx.Commit() return layerSimple, nil }