From a2701f486c6a2b0f7fc862296f8d39066e972291 Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Sun, 14 Jan 2024 11:55:30 -0800 Subject: [PATCH] add more correct session support and use production protobufs this starts to get to a more correct/usable Session --- Makefile | 38 +--------------- buf.gen.yaml | 18 -------- buf.work.yaml | 4 -- go.mod | 13 +++--- go.sum | 26 ++++++----- internal/session/session.go | 40 +++++++++++++++++ internal/vitess/vitess.go | 50 +++++++++++++++++++++ main.go | 87 ++++++++++++++++++++++--------------- 8 files changed, 165 insertions(+), 111 deletions(-) delete mode 100644 buf.gen.yaml delete mode 100644 buf.work.yaml create mode 100644 internal/session/session.go create mode 100644 internal/vitess/vitess.go diff --git a/Makefile b/Makefile index 620317c..20e4b04 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,12 @@ app = ps-http-sim gomod := github.com/mattrobenolt/$(app) -PSDB_PROTO_OUT := types -PSDB_PROTO_ROOT := $(PSDB_PROTO_OUT)/psdb -PSDB_V1ALPHA1 := $(PSDB_PROTO_ROOT)/v1alpha1 - BIN := bin -UNAME_OS := $(shell uname -s) -UNAME_ARCH := $(shell uname -m) - all: $(BIN)/$(app) -proto: \ - $(PSDB_V1ALPHA1)/database.pb.go - clean: clean-bin clean-dist -clean-proto: - rm -rf $(PSDB_PROTO_OUT) - clean-bin: rm -rf $(BIN) @@ -29,32 +16,11 @@ clean-dist: $(BIN): mkdir -p $(BIN) -$(PSDB_PROTO_OUT): - mkdir -p $(PSDB_PROTO_OUT) - GO_INSTALL := env GOBIN=$(PWD)/$(BIN) go install -ldflags "-s -w" -trimpath -$(BIN)/buf: Makefile | $(BIN) - $(GO_INSTALL) github.com/bufbuild/buf/cmd/buf@v1.28.0 - -$(BIN)/protoc-gen-go: Makefile | $(BIN) - $(GO_INSTALL) google.golang.org/protobuf/cmd/protoc-gen-go - -$(BIN)/protoc-gen-connect-go: Makefile | $(BIN) - $(GO_INSTALL) connectrpc.com/connect/cmd/protoc-gen-connect-go - -$(BIN)/protoc-gen-go-vtproto: Makefile | $(BIN) - $(GO_INSTALL) github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.5.0 - $(BIN)/goreleaser: Makefile | $(BIN) $(GO_INSTALL) github.com/goreleaser/goreleaser@v1.22.1 -PROTO_TOOLS := $(BIN)/buf $(BIN)/protoc-gen-go $(BIN)/protoc-gen-connect-go $(BIN)/protoc-gen-go-vtproto -tools: $(PROTO_TOOLS) - -$(PSDB_V1ALPHA1)/database.pb.go: $(PROTO_TOOLS) proto-src/planetscale/psdb/v1alpha1/database.proto | $(PSDB_PROTO_OUT) - $(BIN)/buf generate -v proto-src/planetscale/psdb/v1alpha1/database.proto - $(BIN)/$(app): main.go go.mod go.sum | $(BIN) $(GO_INSTALL) $(gomod) @@ -73,9 +39,9 @@ docker: docker buildx build --target=local --rm -t $(app) . run-mysql: - docker run -it --rm --name $(app)-mysqld -e MYSQL_ALLOW_EMPTY_PASSWORD="true" -e MYSQL_ROOT_PASSWORD="" -p 127.0.0.1:3306:3306 mysql:8.0.29 + docker run -it --rm --name $(app)-mysqld -e MYSQL_ALLOW_EMPTY_PASSWORD="true" -e MYSQL_ROOT_PASSWORD="" -p 127.0.0.1:3306:3306 mysql:8.0.34 publish: clean $(BIN)/goreleaser $(BIN)/goreleaser release -.PHONY: all proto clean clean-proto clean-bin clean-dist tools run run-mysql publish +.PHONY: all clean clean-bin clean-dist run docker run-mysql publish diff --git a/buf.gen.yaml b/buf.gen.yaml deleted file mode 100644 index 8e60b0e..0000000 --- a/buf.gen.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: v1 -plugins: - - name: go - path: bin/protoc-gen-go - out: types - opt: - - paths=source_relative - - name: go-vtproto - path: bin/protoc-gen-go-vtproto - out: types - opt: - - paths=source_relative - - features=marshal+unmarshal+size+pool - - name: connect-go - path: bin/protoc-gen-connect-go - out: types - opt: - - paths=source_relative diff --git a/buf.work.yaml b/buf.work.yaml deleted file mode 100644 index 5a10d1f..0000000 --- a/buf.work.yaml +++ /dev/null @@ -1,4 +0,0 @@ -version: v1 -directories: - - proto-src/planetscale - - proto-src/vitess diff --git a/go.mod b/go.mod index e52ee86..3b1dca1 100644 --- a/go.mod +++ b/go.mod @@ -2,15 +2,15 @@ module github.com/mattrobenolt/ps-http-sim go 1.21 -toolchain go1.21.4 +toolchain go1.21.6 require ( - connectrpc.com/connect v1.12.0 + connectrpc.com/connect v1.14.0 github.com/matoous/go-nanoid/v2 v2.0.0 github.com/planetscale/log v0.0.0-20230818230039-324540f3f1cf - github.com/planetscale/psdb v0.0.0-20230808180222-628a2f94488d - golang.org/x/net v0.18.0 - google.golang.org/protobuf v1.31.0 + github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7 + golang.org/x/net v0.20.0 + google.golang.org/protobuf v1.32.0 vitess.io/vitess v0.18.0 ) @@ -48,6 +48,7 @@ require ( github.com/philhofer/fwd v1.1.2 // indirect github.com/pires/go-proxyproto v0.7.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/planetscale/vitess-types v0.0.0-20230808182149-da48f87540fa // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect @@ -74,7 +75,7 @@ require ( go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.14.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.4.0 // indirect golang.org/x/tools v0.15.0 // indirect diff --git a/go.sum b/go.sum index 97d2ae9..26f9b86 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -connectrpc.com/connect v1.12.0 h1:HwKdOY0lGhhoHdsza+hW55aqHEC64pYpObRNoAgn70g= -connectrpc.com/connect v1.12.0/go.mod h1:3AGaO6RRGMx5IKFfqbe3hvK1NqLosFNP2BxDYTPmNPo= +connectrpc.com/connect v1.14.0 h1:PDS+J7uoz5Oui2VEOMcfz6Qft7opQM9hPiKvtGC01pA= +connectrpc.com/connect v1.14.0/go.mod h1:uoAq5bmhhn43TwhaKdGKN/bZcGtzPW1v+ngDTn5u+8s= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= @@ -234,8 +234,10 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/planetscale/log v0.0.0-20230818230039-324540f3f1cf h1:CrZS7fPVvV/JyAIvWxANPPA8zNlXdqfAQqO4fgEuxJI= github.com/planetscale/log v0.0.0-20230818230039-324540f3f1cf/go.mod h1:iVAMoEFq8Xkpego+6LNR+RVoTAgMOY0Mjtp1PTAH25U= -github.com/planetscale/psdb v0.0.0-20230808180222-628a2f94488d h1:ud5e7kvr1Uf9EY+qe6odddM6rl2LrMFLMzjkpj/Hrps= -github.com/planetscale/psdb v0.0.0-20230808180222-628a2f94488d/go.mod h1:0JRGa3ZPwB34zjqOfcTnPV7hQOlJCO58+tyxMXel/IA= +github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7 h1:dxdoFKWVDlV1gq8UQC8NWCofLjCEjEHw47gfeojgs28= +github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7/go.mod h1:WZmi4gw3rOK+ryd1inGxgfKwoFV04O7xBCqzWzv0/0U= +github.com/planetscale/vitess-types v0.0.0-20230808182149-da48f87540fa h1:juLtMTt8CSth379yqZZh1v8JP9UpI/wQlBpsfo/qhdE= +github.com/planetscale/vitess-types v0.0.0-20230808182149-da48f87540fa/go.mod h1:xzNXoqcNPoV2oI52AwXf+213wzzf46KSOAjGXHrju7U= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -342,8 +344,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +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/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= @@ -416,8 +418,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +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/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= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -482,8 +484,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -658,8 +660,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.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= gopkg.in/DataDog/dd-trace-go.v1 v1.57.0 h1:fhF8rUmpJhXT6wQVKcfm0Wc4VfBwthgLabjQOJR2HV0= gopkg.in/DataDog/dd-trace-go.v1 v1.57.0/go.mod h1:ANES99E9pKUJ22wHBQkMsrt776+lz7V1nwAanwibU7U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/session/session.go b/internal/session/session.go new file mode 100644 index 0000000..f570a11 --- /dev/null +++ b/internal/session/session.go @@ -0,0 +1,40 @@ +package session + +import ( + "math/rand" + + gonanoid "github.com/matoous/go-nanoid/v2" + psdbv1alpha1 "github.com/planetscale/psdb/types/psdb/v1alpha1" + querypb "github.com/planetscale/vitess-types/gen/vitess/query/v16" + vtgatepb "github.com/planetscale/vitess-types/gen/vitess/vtgate/v16" +) + +func UUID(session *psdbv1alpha1.Session) string { + if session != nil && session.VitessSession != nil { + return session.VitessSession.SessionUUID + } + return "" +} + +func New() *psdbv1alpha1.Session { + // we're not doing anything with the signature, and it's opaque bytes + // to clients, so just generate a random 32 bytes + var signature [32]byte + rand.Read(signature[:]) + + session := &psdbv1alpha1.Session{ + Signature: signature[:], + VitessSession: &vtgatepb.Session{ + Options: &querypb.ExecuteOptions{ + IncludedFields: querypb.ExecuteOptions_ALL, + Workload: querypb.ExecuteOptions_UNSPECIFIED, + ClientFoundRows: true, + }, + Autocommit: true, + DDLStrategy: "direct", + SessionUUID: gonanoid.Must(), + EnableSystemSettings: true, + }, + } + return session +} diff --git a/internal/vitess/vitess.go b/internal/vitess/vitess.go new file mode 100644 index 0000000..7a16c0d --- /dev/null +++ b/internal/vitess/vitess.go @@ -0,0 +1,50 @@ +package vitess + +import ( + "context" + "unsafe" + + querypb "github.com/planetscale/vitess-types/gen/vitess/query/v16" + vtrpcpb "github.com/planetscale/vitess-types/gen/vitess/vtrpc/v16" + "vitess.io/vitess/go/sqltypes" + vitessquerypb "vitess.io/vitess/go/vt/proto/query" +) + +// Code returns the error code if it's a vtError. +// If err is nil, it returns ok. +func Code(err error) vtrpcpb.Code { + if err == nil { + return vtrpcpb.Code_OK + } + + // Handle some special cases. + switch err { + case context.Canceled: + return vtrpcpb.Code_CANCELED + case context.DeadlineExceeded: + return vtrpcpb.Code_DEADLINE_EXCEEDED + } + return vtrpcpb.Code_UNKNOWN +} + +func ToVTRPC(err error) *vtrpcpb.RPCError { + if err == nil { + return nil + } + return &vtrpcpb.RPCError{ + Code: Code(err), + Message: err.Error(), + } +} + +func ResultToProto(qr *sqltypes.Result) *querypb.QueryResult { + return unsafeCastQueryResult(sqltypes.ResultToProto3(qr)) +} + +func castTo[RT any, T any](a T) RT { + return (*(*RT)(unsafe.Pointer(&a))) +} + +func unsafeCastQueryResult(qr *vitessquerypb.QueryResult) *querypb.QueryResult { + return castTo[*querypb.QueryResult](qr) +} diff --git a/main.go b/main.go index 0686dfe..7aaf2f0 100644 --- a/main.go +++ b/main.go @@ -15,15 +15,15 @@ import ( gonanoid "github.com/matoous/go-nanoid/v2" "github.com/planetscale/log" "github.com/planetscale/psdb/auth" + psdbv1alpha1 "github.com/planetscale/psdb/types/psdb/v1alpha1" + "github.com/planetscale/psdb/types/psdb/v1alpha1/psdbv1alpha1connect" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/vterrors" - psdbv1alpha1 "github.com/mattrobenolt/ps-http-sim/types/psdb/v1alpha1" - "github.com/mattrobenolt/ps-http-sim/types/psdb/v1alpha1/psdbv1alpha1connect" + "github.com/mattrobenolt/ps-http-sim/internal/session" + "github.com/mattrobenolt/ps-http-sim/internal/vitess" ) var ( @@ -132,7 +132,7 @@ func main() { initConnPool() mux := http.NewServeMux() - mux.Handle(psdbv1alpha1connect.NewDatabaseHandler(&server{})) + mux.Handle(psdbv1alpha1connect.NewDatabaseHandler(server{})) logger.Info("running", log.String("addr", *flagListenAddr), @@ -146,7 +146,7 @@ func main() { type server struct{} -func (s *server) CreateSession( +func (server) CreateSession( ctx context.Context, req *connect.Request[psdbv1alpha1.CreateSessionRequest], ) (*connect.Response[psdbv1alpha1.CreateSessionResponse], error) { @@ -165,9 +165,10 @@ func (s *server) CreateSession( log.String("user", creds.Username()), ) - session := gonanoid.Must() + sess := session.New() + sessionID := session.UUID(sess) - if conn, err := getConn(context.Background(), creds.Username(), string(creds.SecretBytes()), session); err != nil { + if conn, err := getConn(ctx, creds.Username(), string(creds.SecretBytes()), sessionID); err != nil { if strings.Contains(err.Error(), "Access denied for user") { ll.Error("unauthenticated", log.Error(err)) return nil, connect.NewError(connect.CodeUnauthenticated, err) @@ -175,7 +176,7 @@ func (s *server) CreateSession( ll.Warn(err.Error()) return nil, connect.NewError( connect.CodePermissionDenied, - fmt.Errorf("%s: %s", err.Error(), session), + fmt.Errorf("%s: %s", err.Error(), sessionID), ) } ll.Error("failed to connect", log.Error(err)) @@ -193,11 +194,11 @@ func (s *server) CreateSession( Username: creds.Username(), Psid: "planetscale-1", }, - Session: session, + Session: sess, }), nil } -func (s *server) Execute( +func (server) Execute( ctx context.Context, req *connect.Request[psdbv1alpha1.ExecuteRequest], ) (*connect.Response[psdbv1alpha1.ExecuteResponse], error) { @@ -218,21 +219,22 @@ func (s *server) Execute( msg := req.Msg query := msg.Query - session := msg.Session - clientSession := session != "" + sess := msg.Session + clientSession := sess != nil // if there is no session, let's generate a new one if !clientSession { - session = gonanoid.Must() + sess = session.New() } + sessionID := session.UUID(sess) ll = ll.With( log.String("query", query), - log.String("session", session), + log.String("session_id", sessionID), log.Bool("client_session", clientSession), ) - conn, err := getConn(context.Background(), creds.Username(), string(creds.SecretBytes()), session) + conn, err := getConn(ctx, creds.Username(), string(creds.SecretBytes()), sessionID) if err != nil { if strings.Contains(err.Error(), "Access denied for user") { ll.Error("unauthenticated", log.Error(err)) @@ -241,7 +243,7 @@ func (s *server) Execute( ll.Warn(err.Error()) return nil, connect.NewError( connect.CodePermissionDenied, - fmt.Errorf("%s: %s", err.Error(), session), + fmt.Errorf("%s: %s", err.Error(), sessionID), ) } ll.Error("failed to connect", log.Error(err)) @@ -255,13 +257,13 @@ func (s *server) Execute( qr, err := conn.ExecuteFetch(query, int(*flagMySQLMaxRows), true) return connect.NewResponse(&psdbv1alpha1.ExecuteResponse{ - Session: session, - Result: sqltypes.ResultToProto3(qr), - Error: vterrors.ToVTRPC(err), + Session: sess, + Result: vitess.ResultToProto(qr), + Error: vitess.ToVTRPC(err), }), nil } -func (s *server) StreamExecute( +func (server) StreamExecute( ctx context.Context, req *connect.Request[psdbv1alpha1.ExecuteRequest], stream *connect.ServerStream[psdbv1alpha1.ExecuteResponse], @@ -283,21 +285,22 @@ func (s *server) StreamExecute( msg := req.Msg query := msg.Query - session := msg.Session - clientSession := session != "" + sess := msg.Session + clientSession := sess != nil // if there is no session, let's generate a new one if !clientSession { - session = gonanoid.Must() + sess = session.New() } + sessionID := session.UUID(sess) ll = ll.With( log.String("query", query), - log.String("session", session), + log.String("session_id", sessionID), log.Bool("client_session", clientSession), ) - conn, err := getConn(context.Background(), creds.Username(), string(creds.SecretBytes()), session) + conn, err := getConn(ctx, creds.Username(), string(creds.SecretBytes()), sessionID) if err != nil { if strings.Contains(err.Error(), "Access denied for user") { ll.Error("unauthenticated", log.Error(err)) @@ -306,7 +309,7 @@ func (s *server) StreamExecute( ll.Warn(err.Error()) return connect.NewError( connect.CodePermissionDenied, - fmt.Errorf("%s: %s", err.Error(), session), + fmt.Errorf("%s: %s", err.Error(), sessionID), ) } ll.Error("failed to connect", log.Error(err)) @@ -320,9 +323,9 @@ func (s *server) StreamExecute( ll.Info("send msg") if err := stream.Send(&psdbv1alpha1.ExecuteResponse{ - Session: session, - Result: sqltypes.ResultToProto3(qr), - Error: vterrors.ToVTRPC(err), + Session: sess, + Result: vitess.ResultToProto(qr), + Error: vitess.ToVTRPC(err), }); err != nil { ll.Error("send failed", log.Error(err)) return err @@ -330,9 +333,9 @@ func (s *server) StreamExecute( ll.Info("send msg") if err := stream.Send(&psdbv1alpha1.ExecuteResponse{ - Session: session, - Result: sqltypes.ResultToProto3(qr), - Error: vterrors.ToVTRPC(err), + Session: sess, + Result: vitess.ResultToProto(qr), + Error: vitess.ToVTRPC(err), }); err != nil { ll.Error("send failed", log.Error(err)) return err @@ -341,6 +344,20 @@ func (s *server) StreamExecute( return nil } +func (server) CloseSession( + ctx context.Context, + req *connect.Request[psdbv1alpha1.CloseSessionRequest], +) (*connect.Response[psdbv1alpha1.CloseSessionResponse], error) { + return connect.NewResponse(&psdbv1alpha1.CloseSessionResponse{}), nil +} + +func (server) Prepare( + ctx context.Context, + req *connect.Request[psdbv1alpha1.PrepareRequest], +) (*connect.Response[psdbv1alpha1.PrepareResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("not implemented")) +} + func initConnPool() { connPool = make(map[mysqlConnKey]*timedConn) go func() { @@ -348,8 +365,8 @@ func initConnPool() { // this is just very quick and simple, it has race conditions, // but I don't care for this. timer := time.NewTicker(*flagMySQLIdleTimeout) - for { - <-timer.C + defer timer.Stop() + for range timer.C { expiration := time.Now().Add(-*flagMySQLIdleTimeout) expired := make([]mysqlConnKey, 0)