diff --git a/go-caller/main.go b/go-caller/main.go index f0b53e96..7dc73fc2 100644 --- a/go-caller/main.go +++ b/go-caller/main.go @@ -2,137 +2,218 @@ package main import ( "context" - "fmt" "log" "net/http" "os" + "os/signal" + "sync" + "sync/atomic" + "syscall" "time" + retrieve "github.com/Meesho/BharatMLStack/go-sdk/pkg/proto/onfs/retrieve" "github.com/gin-gonic/gin" - retrieve "github.com/Meesho/BharatMLStack/go-sdk/pkg/proto/onfs/retrieve" // adjust path "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" ) -// ApiResponse matches your Rust ApiResponse struct -type ApiResponse struct { - Success bool `json:"success"` - Data *string `json:"data,omitempty"` - Error *string `json:"error,omitempty"` - Message string `json:"message"` +// Request body structures for retrieve_features endpoint +type RetrieveFeaturesRequest struct { + EntityLabel string `json:"entity_label" binding:"required"` + FeatureGroups []FeatureGroupRequest `json:"feature_groups" binding:"required"` + KeysSchema []string `json:"keys_schema" binding:"required"` + Keys []KeysRequest `json:"keys" binding:"required"` +} +type FeatureGroupRequest struct { + Label string `json:"label" binding:"required"` + FeatureLabels []string `json:"feature_labels" binding:"required"` +} +type KeysRequest struct { + Cols []string `json:"cols" binding:"required"` } -// AppState stores gRPC client -type AppState struct { - client retrieve.FeatureServiceClient +const ( + // CONNECTION_POOL_SIZE defines the number of gRPC connections in the pool + // Each HTTP/2 connection supports ~100 concurrent streams + // With 16 connections: 16 * 100 = 1,600 concurrent streams capacity + CONNECTION_POOL_SIZE = 16 +) + +// ClientPool manages a pool of gRPC clients for load distribution +type ClientPool struct { + clients []retrieve.FeatureServiceClient + conns []*grpc.ClientConn + counter uint64 // Atomic counter for round-robin selection } -// retrieveFeatures handles HTTP request -func (s *AppState) retrieveFeatures(c *gin.Context) { - authToken := "atishay" - callerID := "test-3" +// NewClientPool creates a new pool of gRPC connections and clients +func NewClientPool(address string) (*ClientPool, error) { + clients := make([]retrieve.FeatureServiceClient, 0, CONNECTION_POOL_SIZE) + conns := make([]*grpc.ClientConn, 0, CONNECTION_POOL_SIZE) + + for i := 0; i < CONNECTION_POOL_SIZE; i++ { + conn, err := grpc.NewClient( + address, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: 30 * time.Second, + Timeout: 10 * time.Second, + PermitWithoutStream: true, + }), + grpc.WithInitialWindowSize(2*1024*1024), // 2MB stream window + grpc.WithInitialConnWindowSize(4*1024*1024), // 4MB connection window + ) + if err != nil { + // Cleanup already created connections on error + for _, c := range conns { + _ = c.Close() + } + return nil, err + } + conns = append(conns, conn) + clients = append(clients, retrieve.NewFeatureServiceClient(conn)) + } - result, err := s.retrieveFeaturesInternal(authToken, callerID) - if err != nil { - log.Printf("āŒ gRPC Error: %v", err) - errMsg := err.Error() - c.JSON(http.StatusInternalServerError, ApiResponse{ - Success: false, - Data: nil, - Error: &errMsg, - Message: "Failed to retrieve features", - }) - return + return &ClientPool{ + clients: clients, + conns: conns, + }, nil +} + +// Next returns the next client from the pool using round-robin distribution +func (p *ClientPool) Next() retrieve.FeatureServiceClient { + idx := atomic.AddUint64(&p.counter, 1) - 1 + return p.clients[idx%uint64(len(p.clients))] +} + +// Close closes all connections in the pool +func (p *ClientPool) Close() error { + var wg sync.WaitGroup + errChan := make(chan error, len(p.conns)) + + for i := range p.conns { + wg.Add(1) + go func(c *grpc.ClientConn) { + defer wg.Done() + if err := c.Close(); err != nil { + errChan <- err + } + }(p.conns[i]) + } + + wg.Wait() + close(errChan) + + // Collect any errors + var errs []error + for err := range errChan { + errs = append(errs, err) } - data := fmt.Sprintf("%v", result) - c.JSON(http.StatusOK, ApiResponse{ - Success: true, - Data: &data, - Error: nil, - Message: "Features retrieved successfully", - }) + if len(errs) > 0 { + return errs[0] // Return first error + } + return nil } -// retrieveFeaturesInternal calls gRPC backend -func (s *AppState) retrieveFeaturesInternal(authToken, callerID string) (*retrieve.Result, error) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() +// AppState stores gRPC client pool and metadata +type AppState struct { + pool *ClientPool + metadata metadata.MD +} - // Attach metadata - md := metadata.New(map[string]string{ - "online-feature-store-auth-token": authToken, - "online-feature-store-caller-id": callerID, - }) - ctx = metadata.NewOutgoingContext(ctx, md) +func (s *AppState) handler(c *gin.Context) { + var requestBody RetrieveFeaturesRequest + if err := c.ShouldBindJSON(&requestBody); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } - // Build gRPC request + ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second) + defer cancel() + ctx = metadata.NewOutgoingContext(ctx, s.metadata) + + // Convert request body to protobuf Query + featureGroups := make([]*retrieve.FeatureGroup, 0, len(requestBody.FeatureGroups)) + for _, fg := range requestBody.FeatureGroups { + featureGroups = append(featureGroups, &retrieve.FeatureGroup{ + Label: fg.Label, + FeatureLabels: fg.FeatureLabels, + }) + } + keys := make([]*retrieve.Keys, 0, len(requestBody.Keys)) + for _, k := range requestBody.Keys { + keys = append(keys, &retrieve.Keys{ + Cols: k.Cols, + }) + } req := &retrieve.Query{ - EntityLabel: "catalog", - FeatureGroups: []*retrieve.FeatureGroup{ - { - Label: "derived_fp32", - FeatureLabels: []string{ - "clicks_by_views_3_days", - }, - }, - }, - KeysSchema: []string{"catalog_id"}, - Keys: []*retrieve.Keys{ - {Cols: []string{"176"}}, - {Cols: []string{"179"}}, - }, + EntityLabel: requestBody.EntityLabel, + FeatureGroups: featureGroups, + KeysSchema: requestBody.KeysSchema, + Keys: keys, } - log.Println("šŸ“” Retrieving features...") - resp, err := s.client.RetrieveFeatures(ctx, req) + client := s.pool.Next() + resp, err := client.RetrieveFeatures(ctx, req) if err != nil { - return nil, err + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return } - return resp, nil + c.JSON(http.StatusOK, gin.H{"status": "success", "response": resp}) } func main() { - log.Println("Connecting to feature store...") + log.Printf("Starting go-caller with connection pool (size: %d)", CONNECTION_POOL_SIZE) + gin.SetMode(gin.ReleaseMode) - // gRPC channel - conn, err := grpc.Dial( - "online-feature-store-api.int.meesho.int:80", - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) + pool, err := NewClientPool("online-feature-store-api.int.meesho.int:80") if err != nil { - log.Fatalf("Failed to connect gRPC: %v", err) + log.Fatalf("Failed to create gRPC connection pool: %v", err) } - defer conn.Close() - - client := retrieve.NewFeatureServiceClient(conn) - state := &AppState{client: client} - - // Gin server - router := gin.Default() - - // Allow CORS permissive (similar to Rust) - router.Use(func(c *gin.Context) { - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") - c.Writer.Header().Set("Access-Control-Allow-Headers", "*") - if c.Request.Method == "OPTIONS" { - c.AbortWithStatus(http.StatusNoContent) - return + defer func() { + log.Println("Closing gRPC connection pool...") + if err := pool.Close(); err != nil { + log.Printf("Error closing gRPC connection pool: %v", err) } - c.Next() - }) + }() + + state := &AppState{ + pool: pool, + metadata: metadata.MD{ + "online-feature-store-auth-token": []string{"atishay"}, + "online-feature-store-caller-id": []string{"test-3"}, + }, + } - router.POST("/retrieve-features", state.retrieveFeatures) + r := gin.New() + r.POST("/retrieve-features", state.handler) - port := "8081" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") + srv := &http.Server{ + Addr: ":8081", + Handler: r, } - log.Printf("šŸš€ Starting go-caller on http://0.0.0.0:%s\n", port) - if err := router.Run("0.0.0.0:" + port); err != nil { - log.Fatalf("Failed to start server: %v", err) + // Graceful shutdown + go func() { + log.Println("šŸš€ Go gRPC Client running on http://0.0.0.0:8081") + if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Fatalf("Failed to start server: %v", err) + } + }() + + // Wait for interrupt signal to gracefully shutdown the server + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + log.Println("Shutting down server...") + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + log.Fatalf("Server forced to shutdown: %v", err) } + log.Println("Server exited") } diff --git a/rust-caller-new/Cargo.lock b/rust-caller-new/Cargo.lock index ee343cc2..a0a9e53f 100644 --- a/rust-caller-new/Cargo.lock +++ b/rust-caller-new/Cargo.lock @@ -2,35 +2,20 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "async-stream" @@ -115,10 +100,10 @@ dependencies = [ "axum-core 0.4.5", "bytes", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "itoa", "matchit", @@ -165,7 +150,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", @@ -177,21 +162,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.21.7" @@ -206,21 +176,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "either" @@ -241,7 +211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -318,27 +288,21 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.4+wasi-0.2.4", + "wasip2", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "h2" version = "0.3.27" @@ -351,7 +315,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.1", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -366,9 +330,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -389,12 +353,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -416,7 +379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -427,7 +390,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -470,15 +433,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "httparse", "httpdate", @@ -503,15 +466,15 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.7.0", + "hyper 1.8.1", "pin-project-lite", "tokio", "tower-service", @@ -529,23 +492,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.15.5", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", + "hashbrown 0.16.1", ] [[package]] @@ -559,9 +511,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "lazy_static" @@ -571,15 +523,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "linux-raw-sys" @@ -589,19 +535,18 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "matchers" @@ -620,9 +565,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "mime" @@ -630,24 +575,15 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -658,20 +594,11 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", + "windows-sys 0.61.2", ] [[package]] @@ -682,9 +609,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -692,15 +619,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -716,7 +643,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.11.1", + "indexmap 2.12.1", ] [[package]] @@ -772,9 +699,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -834,9 +761,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -879,18 +806,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.11.2" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -900,9 +827,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -911,16 +838,18 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "rust-caller-new" +name = "rust_service" version = "0.1.0" dependencies = [ "axum 0.7.9", + "http-body 1.0.1", "prost", + "prost-types", "serde", "serde_json", "tokio", @@ -932,24 +861,17 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustix" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9621e389a110cae094269936383d69b869492f03e5c1ed2d575a53c029d4441d" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.11.0", - "linux-raw-sys 0.9.4", - "windows-sys 0.61.0", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] @@ -960,9 +882,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "scopeguard" @@ -972,18 +894,28 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -992,24 +924,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -1035,10 +969,11 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -1066,19 +1001,19 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "syn" -version = "2.0.106" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -1099,15 +1034,15 @@ checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "tempfile" -version = "3.21.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1121,23 +1056,19 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1152,9 +1083,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -1174,9 +1105,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -1267,9 +1198,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bytes", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "pin-project-lite", @@ -1292,9 +1223,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -1304,9 +1235,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -1315,9 +1246,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -1334,35 +1265,22 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-serde" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" -dependencies = [ - "serde", - "tracing-core", -] - [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex-automata", - "serde", - "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", - "tracing-serde", ] [[package]] @@ -1373,9 +1291,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "valuable" @@ -1399,25 +1317,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.4+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -1428,31 +1340,22 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.0", + "windows-link", ] [[package]] @@ -1473,19 +1376,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -1496,9 +1399,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -1508,9 +1411,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -1520,9 +1423,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -1532,9 +1435,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -1544,9 +1447,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -1556,9 +1459,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -1568,9 +1471,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -1580,32 +1483,38 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "wit-bindgen" -version = "0.45.1" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" diff --git a/rust-caller-new/Cargo.toml b/rust-caller-new/Cargo.toml index 4d2fd861..60e0c458 100644 --- a/rust-caller-new/Cargo.toml +++ b/rust-caller-new/Cargo.toml @@ -4,19 +4,24 @@ version = "0.1.0" edition = "2021" [dependencies] -tokio = { version = "1", features = ["full", "tracing"] } -tonic = "0.11" -prost = "0.12" -tower = "0.4" axum = "0.7" +tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tower-http = { version = "0.5", features = ["cors", "trace"] } -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } +tonic = "0.14" +tonic-prost = "0.14" +prost = "0.14" +prost-types = "0.14" +base64 = "0.21" +quinn = "0.11" +rustls = { version = "0.23", features = ["ring"] } +rustls-pemfile = "2.0" +rustls-native-certs = "0.6" +clap = { version = "4", features = ["derive"] } +http = "1.0" +h3-quinn = "0.0" +tonic-h3 = { git = "https://github.com/youyuanwu/tonic-h3.git", default-features = false, features = ["quinn"] } [build-dependencies] -tonic-build = "0.11" - -[workspace] +tonic-prost-build = "0.14" diff --git a/rust-caller-new/build.rs b/rust-caller-new/build.rs index da9e3a62..7916e1ae 100644 --- a/rust-caller-new/build.rs +++ b/rust-caller-new/build.rs @@ -1,13 +1,6 @@ -fn main() { - tonic_build::configure() - .build_server(true) - .compile( - &["proto/retrieve.proto"], - &["proto"], - ) - .unwrap(); - - println!("cargo:rerun-if-changed=proto/retrieve.proto"); - println!("cargo:rerun-if-changed=proto/"); +fn main() -> Result<(), Box> { + // Use tonic-prost-build as shown in tonic-h3 tests + tonic_prost_build::compile_protos("proto/retrieve.proto")?; + Ok(()) } diff --git a/rust-caller-new/latency_test.js b/rust-caller-new/latency_test.js new file mode 100644 index 00000000..cfdcbbbc --- /dev/null +++ b/rust-caller-new/latency_test.js @@ -0,0 +1,702 @@ +import http from "k6/http"; +import { check } from "k6"; + +export const options = { + duration: "10m", + vus: 500, + rps: 500, + thresholds: { + http_req_duration: ["p(50)<50", "p(90)<100", "p(99)<200"], + }, +}; + +const requestPayload = JSON.stringify({ + "entity_label": "catalog", + "feature_groups": [ + { + "label": "derived_fp32", + "feature_labels": [ + "max_product_price_percentile", + "orders_by_views_56day_percentile", + "catalog__platform_orders_by_clicks_28_days_percentile_bin", + "orders_by_views_28day_bin_percentile", + "min_product_price_percentile", + "orders_14day_percentile", + "total_rated_orders_bin_percentile", + "orders_28day_percentile", + "clicks_by_views_1day_percentile", + "min_product_price_bin_percentile", + "clicks_by_views_3day_percentile", + "log_orders_1day", + "total_rated_orders_percentile", + "clicks_by_views_5day", + "views_56day_percentile", + "log_clicks_7day", + "views_3day_percentile", + "orders_by_views_28day_percentile", + "orders_7day_percentile", + "orders_by_clicks_14day_percentile", + "clicks_by_views_5day_percentile", + "log_clicks_56day", + "orders_by_clicks_28day_percentile", + "orders_3day_percentile", + "clicks_by_views_56day_percentile", + "log_orders_14day", + "log_views_5day", + "max_product_price_percentile_bin", + "log_clicks_3day", + "views_7day_percentile", + "orders_by_views_14day_percentile", + "log_clicks_28day", + "log_views_1day", + "log_orders_7day", + "clicks_by_views_1day__bin_percentile", + "clicks_56day_percentile", + "clicks_5day_percentile", + "catalog__platform_orders_by_clicks_3_days", + "orders_by_clicks_3day_percentile", + "orders_by_clicks_1day_percentile", + "orders_by_clicks_5day_percentile", + "log_clicks_1day", + "orders_by_clicks_7day_percentile", + "log_orders_3day", + "log_orders_56day", + "clicks_7day_percentile", + "orders_by_views_3day_percentile", + "log_views_56day", + "clicks_3day_percentile", + "orders_by_views_7day_percentile", + "clicks_1day_percentile", + "orders_by_views_5day_percentile", + "log_clicks_14day", + "clicks_by_views_7day_percentile", + "clicks_28day_percentile", + "orders_5day_percentile", + "orders_by_views_1day_percentile", + "log_orders_28day", + "clicks_by_views_28day_bin_percentile", + "log_views_7day", + "views_5day_percentile", + "views_28day_percentile", + "log_views_28day", + "views_1day_percentile", + "orders_1day_percentile", + "log_views_3day", + "orders_by_clicks_56day_percentile", + "log_clicks_5day", + "orders_56day_percentile", + "clicks_by_views_14day_percentile", + "clicks_by_views_28day_percentile", + "ctr_bin_normalized_clicks_by_views_1_days", + "sscat_normalized_clicks_by_views_1_days", + "position_coec_7_days", + "pdp__hour_coec_7_days", + "hour_coec_1_days", + "pdp__sscat_normalized_clicks_by_views_7_days", + "search__clicks_by_views_1_days", + "pdp__position_coec_7_days", + "search__clicks_by_views_3_days", + "hour_coec_30_days", + "search__active_days_normalized_clicks_by_views_3_days", + "pdp__clicks_by_views_7_days", + "clicks_by_views_14_days", + "hour_coec_14_days", + "search__sscat_normalized_clicks_by_views_1_days", + "search__hour_coec_1_days", + "clicks_by_views_30_days", + "position_coec_3_days", + "search__active_days_normalized_clicks_by_views_1_days", + "search__position_coec_7_days", + "clicks_by_active_days_14_days", + "search__clicks_by_active_days_7_days", + "pdp__hour_coec_14_days", + "search__active_days_normalized_clicks_by_views_7_days", + "search__hour_coec_14_days", + "hour_expected_clicks_1_days", + "position_coec_14_days", + "search__clicks_by_views_7_days", + "search__hour_coec_3_days", + "position_expected_clicks_1_days", + "clicks_by_views_3_days", + "pdp__sscat_normalized_clicks_by_views_30_days", + "search__position_coec_30_days", + "pdp__clicks_by_active_days_7_days", + "search__position_coec_3_days", + "search__active_days_normalized_clicks_by_views_14_days", + "search__clicks_by_views_14_days", + "pdp__clicks_by_views_1_days", + "search__sscat_normalized_clicks_by_views_30_days", + "pdp__clicks_by_views_14_days", + "hour_coec_7_days", + "pdp__hour_coec_30_days", + "search__hour_coec_7_days", + "search__sscat_normalized_clicks_by_views_7_days", + "sscat_normalized_clicks_by_views_7_days", + "pdp__clicks_by_views_3_days", + "search__position_coec_1_days", + "search__sscat_normalized_clicks_by_views_14_days", + "search__clicks_by_views_30_days", + "clicks_by_views_1_days", + "pdp__position_coec_30_days", + "clicks_by_views_7_days", + "position_coec_1_days", + "pdp__hour_coec_1_days", + "search__hour_coec_30_days", + "sscat_normalized_clicks_by_views_30_days", + "search__sscat_normalized_clicks_by_views_3_days", + "position_coec_30_days", + "pdp__clicks_by_views_30_days", + "orders_by_clicks_laplace_28day", + "clicks_by_views_laplace_7day", + "orders_by_views_laplace_1day", + "clicks_by_views_laplace_3day", + "clicks_by_views_laplace_56day", + "catalog__ads_orders_by_clicks_14_days__te_laplace", + "orders_by_clicks_laplace_3day", + "orders_by_views_laplace_28day", + "orders_by_clicks_laplace_56day", + "orders_by_clicks_laplace_7day", + "orders_by_views_laplace_5day", + "clicks_by_views_laplace_5day", + "orders_by_views_laplace_3day", + "orders_by_views_laplace_56day", + "catalog__ads_orders_by_views_14_days__te_laplace", + "orders_by_clicks_laplace_5day", + "clicks_by_views_laplace_1day", + "orders_by_clicks_laplace_1day", + "orders_by_views_laplace_7day", + "clicks_by_views_laplace_28day", + "laplace_cbyv_by_platform_cbyv_7day", + "laplace_cbyv_by_platform_cbyv_56day", + "laplace_obyv_by_platform_obyv_1day", + "laplace_cbyv_by_platform_cbyv_3day", + "laplace_obyv_by_platform_obyv_56day", + "laplace_obyc_by_platform_obyc_56day", + "laplace_obyc_by_platform_obyc_7day", + "laplace_obyv_by_platform_obyv_5day", + "laplace_obyc_by_platform_obyc_3day", + "laplace_obyc_by_platform_obyc_28day", + "laplace_obyv_by_platform_obyv_28day", + "laplace_cbyv_by_platform_cbyv_5day", + "laplace_obyc_by_platform_obyc_5day", + "laplace_cbyv_by_platform_cbyv_1day", + "laplace_cbyv_by_platform_cbyv_28day", + "laplace_obyv_by_platform_obyv_3day", + "catalog__base_cpc", + "laplace_obyv_by_platform_obyv_7day", + "laplace_obyc_by_platform_obyc_1day", + "orders_by_views_3_days_percentile", + "views_7_days_percentile", + "orders_by_clicks_56_days_percentile", + "orders_by_clicks_5_days_percentile", + "clicks_by_views_28_days_percentile", + "orders_1_days__te_log", + "search__orders_by_views_3_days_percentile", + "orders_3_days__te_log", + "orders_1_days_percentile", + "orders_7_days_percentile", + "orders_7_days__te_log", + "search__orders_by_clicks_3_days_percentile", + "search__clicks_by_views_1_days_percentile_bin", + "search__clicks_56_days_percentile", + "search__orders_by_views_28_days_percentile_bin", + "orders_by_views_7_days_percentile_bin", + "orders_by_clicks_3_days_percentile", + "search__clicks_by_views_1_days_percentile", + "search__orders_by_clicks_1_days_percentile_bin", + "orders_by_views_14_days_percentile", + "search__orders_by_views_28_days_percentile", + "search__orders_by_views_56_days_percentile_bin", + "orders_by_views_1_days_percentile", + "orders_by_clicks_14_days_percentile", + "search__orders_by_views_14_days_percentile", + "search__orders_by_views_1_days_percentile", + "clicks_by_views_14_days_percentile", + "search__orders_by_views_5_days_percentile_bin", + "clicks_3_days_percentile", + "clicks_by_views_3_days_percentile", + "orders_by_clicks_28_days_percentile", + "search__orders_by_clicks_56_days_percentile", + "search__clicks_by_views_28_days_percentile", + "search__orders_by_clicks_7_days_percentile_bin", + "search__clicks_by_views_14_days_percentile_bin", + "orders_by_clicks_7_days", + "orders_by_clicks_3_days_percentile_bin", + "orders_by_views_3_days_percentile_bin", + "views_28_days_percentile", + "clicks_by_views_7_days_percentile", + "clicks_by_views_1_days_percentile", + "clicks_56_days__te_log", + "orders_by_views_28_days_percentile", + "search__orders_by_clicks_7_days_percentile", + "search__orders_by_clicks_1_days_percentile", + "orders_by_clicks_1_days_percentile", + "orders_by_clicks_7_days_percentile", + "orders_by_views_5_days_percentile", + "search__orders_by_views_14_days_percentile_bin", + "search__orders_by_clicks_3_days_percentile_bin", + "search__orders_by_views_5_days_percentile", + "clicks_7_days_percentile", + "views_56_days_percentile_bin", + "orders_by_clicks_7_days_percentile_bin", + "search__orders_1_days_percentile", + "clicks_28_days__te_log", + "orders_by_views_56_days_percentile", + "orders_by_clicks_1_days_percentile_bin", + "search__orders_by_views_56_days_percentile", + "views_3_days_percentile", + "orders_by_views_7_days_percentile", + "search__orders_by_views_7_days_percentile", + "clicks_28_days_percentile", + "search__orders_by_views_1_days_percentile_bin", + "orders_3_days_percentile", + "orders_28_days_percentile", + "clicks_by_views_56_days_percentile", + "num_rating_3_By_num_rating", + "qr_orders_by_sub_orders_28day", + "num_rating_4_By_num_rating", + "catalog__nqd_28_days", + "catalog__num_rating_3_By_num_rating_56_days", + "rtos_by_net_orders", + "nqp_28day", + "net_orders_by_gross_orders_28day", + "catalog__qr_orders_By_return_orders_90_days", + "rating_avg", + "rtos_by_gross_orders", + "net_orders_by_gross_orders_90day", + "num_review_By_num_rating", + "catalog__wfr_orders_By_return_orders", + "catalog__num_rating_3_By_num_rating_90_days", + "catalog__mean_price_90_days", + "rtos_by_net_orders_90day", + "catalog__num_rating_3_By_num_rating_28_days", + "num_img_review_by_num_review", + "avg_ratings_7day", + "num_review_By_num_rating_7day", + "nqp_by_nqd_90day", + "nqp", + "nqd", + "catalog__avg_ratings_28_days", + "net_orders_by_gross_orders_56day", + "catalog__nqp_90_days", + "user_cancelled_by_net_orders_7day", + "return_orders_by_sub_orders", + "cancellations_by_gross_orders_90day", + "cancellations_by_net_orders_7day", + "qr_orders_by_sub_orders", + "catalog__total_helpful_review_By_num_review", + "catalog__total_o2d_delay_By_total_orders_28_days", + "return_orders_by_sub_orders_90day", + "nqp_By_nqd_7day", + "nqp_by_nqd_28day", + "catalog__user_cancelled_By_net_orders", + "cancellations_by_net_orders_56day", + "catalog__num_rating_4_By_num_rating_7_days", + "catalog__net_orders_By_gross_orders_7_days", + "rtos_by_gross_orders_28day", + "avg_ratings_56day", + "total_s2d_delay_by_total_orders_28day", + "nqp_by_nqd", + "num_rating_5_by_num_rating", + "count_reviews_with_helpful_by_num_review_28day", + "rtos_by_gross_orders_56day", + "user_cancelled_by_net_orders_28day", + "catalog__return_orders_By_sub_orders_28_days", + "wfr_orders_by_sub_orders", + "num_review_by_num_rating_28day", + "wfr_orders_by_sub_orders_28day", + "num_review_by_num_rating_90day", + "catalog__num_rating_1_By_num_rating_5_56_days", + "catalog__num_rating_3_By_num_rating_7_days", + "nqp_7day", + "sscat_standardized_cat_predicted_nqd_wd_sigmoid", + "net_orders_by_gross_orders", + "cancellations_by_net_orders", + "return_orders_by_sub_orders_56day", + "cancellations_by_gross_orders", + "catalog__rtos_By_gross_orders_7_days", + "catalog__total_o2d_delay_By_total_orders", + "catalog__total_o2s_delayed_orders_By_total_orders_56_days", + "catalog__nqd_7_days", + "catalog__num_rating_5_By_num_rating_7_days", + "user_cancelled_by_net_orders_56day", + "cancellations_by_net_orders_28day", + "sscat__price_asp", + "asp_sscat_percentile", + "price_shipping_percent", + "price_cheapest_duplicate_diff_percent", + "sscat_asp_price_arp_diff_percent", + "price_wdrp_depth_percent", + "price_sscat_percentile", + "price_decrease_percent_decay", + "arp_sscat_percentile", + "price_discount_percent", + "catalog__price_decrease_pct", + "mrp_sscat_percentile", + "price_increase_percent_decay", + "sscat_asp_price_arp_diff", + "price_discount", + "catalog__user_risk_weighted_orders_90_days", + "od_between_25p_to_50p_user_api_user_orders_percentage_90day", + "high_risk_user_orders_percentage", + "od_less_than_25p_user_api_user_orders_percentage_90day", + "od_2_4_order_users_orders_percentage_90day", + "od_more_than_75p_user_aov_user_orders_percentage_90day", + "od_20_plus_order_users_orders_percentage_90day", + "avg_orders_weighted_aov_90day", + "low_risk_user_orders_percentage", + "od_5_10_order_users_orders_percentage", + "od_2_4_order_users_orders_percentage", + "low_risk_user_orders_percentage_90day", + "od_10_20_order_users_orders_percentage", + "catalog__between_50p_to_75p_user_aov_user_orders_percentage_90_days", + "od_0_1_order_users_orders_percentage_90day", + "avg_orders_weighted_api_90day", + "od_less_than_25p_user_aov_user_orders_percentage_90day", + "od_0_1_order_users_orders_percentage", + "od_5_10_order_users_orders_percentage_90day", + "od_between_25p_to_50p_user_aov_user_orders_percentage_90day", + "od_more_than_75p_user_api_user_orders_percentage_90day", + "od_between_50p_to_75p_user_api_user_orders_percentage_90day", + "catalog__high_risk_user_orders_percentage_90_days", + "od_20_plus_order_users_orders_percentage", + "catalog__10_20_order_users_orders_percentage_90_days", + "catalog__ads_clicks_by_views_56_days_percentile", + "catalog__ads_orders_by_views_1_days_percentile_bin", + "catalog__ads_orders_by_views_56_days_percentile_bin", + "catalog__ads_clicks_by_views_28_days_percentile", + "catalog__ads_orders_by_views_14_days_percentile_bin", + "clicks_28day_percentile", + "catalog__ads_orders_by_views_3_days_percentile", + "catalog__ads_clicks_by_views_28_days_percentile_bin", + "catalog__ads_orders_by_clicks_5_days_percentile", + "orders_56day_percentile", + "catalog__ads_orders_14_days_percentile", + "clicks_56day_percentile", + "catalog__ads_clicks_by_views_5_days", + "catalog__ads_orders_by_views_7_days_percentile", + "views_1day_percentile", + "catalog__ads_orders_by_clicks_28_days_percentile_bin", + "catalog__ads_orders_by_clicks_7_days_percentile_bin", + "catalog__ads_orders_by_views_56_days_percentile", + "clicks_7day_percentile", + "catalog__ads_orders_by_views_7_days_percentile_bin", + "clicks_3day_percentile", + "catalog__ads_orders_by_views_28_days_percentile_bin", + "catalog__ads_orders_by_clicks_1_days_percentile_bin", + "views_56day_percentile", + "catalog__ads_orders_by_clicks_56_days_percentile_bin", + "views_5day_percentile", + "catalog__ads_clicks_by_views_3_days_percentile_bin", + "catalog__ads_orders_by_clicks_7_days_percentile", + "catalog__ads_orders_by_views_28_days_percentile", + "catalog__ads_clicks_by_views_7_days_percentile", + "catalog__ads_orders_by_clicks_3_days_percentile", + "catalog__ads_clicks_by_views_1_days_percentile", + "catalog__ads_orders_by_clicks_3_days_percentile_bin", + "catalog__ads_orders_by_clicks_56_days_percentile", + "catalog__ads_orders_by_clicks_28_days_percentile", + "catalog__ads_orders_by_clicks_14_days", + "catalog__ads_clicks_by_views_14_days_percentile_bin", + "orders_3day_percentile", + "catalog__ads_orders_by_clicks_14_days_percentile", + "orders_1day_percentile", + "views_28day_percentile", + "catalog__ads_clicks_by_views_1_days_percentile_bin", + "orders_5day_percentile", + "catalog__ads_clicks_by_views_5_days_percentile_bin", + "orders_28day_percentile", + "catalog__ads_orders_by_views_5_days_percentile", + "orders_7day_percentile", + "catalog__ads_orders_by_views_5_days_percentile_bin", + "catalog__ads_orders_by_views_1_days_percentile", + "catalog__ads_clicks_by_views_56_days_percentile_bin", + "catalog__ads_clicks_by_views_14_days_percentile", + "catalog__ads_orders_by_views_14_days_percentile", + "views_3day_percentile", + "clicks_5day_percentile", + "catalog__ads_clicks_by_views_56_days", + "catalog__ads_clicks_by_views_5_days_percentile", + "catalog__ads_orders_by_views_3_days_percentile_bin", + "clicks_1day_percentile", + "views_7day_percentile", + "catalog__ads_orders_by_clicks_5_days_percentile_bin", + "catalog__ads_clicks_by_views_3_days_percentile", + "catalog__ads_clicks_by_views_7_days_percentile_bin", + "catalog__ads_orders_by_clicks_1_days_percentile", + "catalog__ads_orders_by_clicks_14_days_percentile_bin", + "search__orders_by_views_7_days_percentile", + "search__orders_by_clicks_1_days_percentile_bin", + "search__orders_by_views_1_days_percentile", + "search__orders_by_views_28_days_percentile_bin", + "search__clicks_by_views_3_days_percentile", + "search__orders_by_clicks_7_days_percentile", + "search__orders_by_views_5_days_percentile_bin", + "search__orders_by_views_14_days_percentile_bin", + "search__orders_by_clicks_7_days_percentile_bin", + "search__orders_by_views_3_days_percentile", + "search__clicks_by_views_14_days_percentile_bin", + "search__clicks_by_views_14_days_percentile", + "search__orders_by_views_5_days_percentile", + "search__clicks_by_views_28_days_percentile", + "search__clicks_by_views_1_days_percentile_bin", + "search__orders_by_views_14_days_percentile", + "log_reviews", + "price_change_percent_dec", + "rating_30day", + "price_change_percent_inc", + "cancel_percent", + "price_diff_with_p70", + "rating_90day", + "asp", + "final_nqd", + "diff_bw_asp_and_arp", + "avg_rating", + "rto_percent", + "return_percent", + "odnr_score", + "rating_60day", + "sscat_price_clicks_by_views_56day_percentile_bin_percentage", + "sscat_rating_orders_by_views_56day_percentile_bin_percentage", + "rating_orders_56day_percentile", + "sscat_rating_clicks_by_views_56day_percentile_bin_percentage", + "rating_views_56day_percentile", + "sscat_price_orders_by_views_56day_percentile_bin_percentage", + "catalog_rating", + "sscat_price_orders_by_clicks_56day_percentile_bin_percentage", + "price_clicks_56day_percentile", + "price_orders_56day_percentile", + "sscat_rating_orders_by_clicks_56day_percentile_bin_percentage", + "price_views_56day_percentile", + "rating_clicks_56day_percentile", + "catalog__platform_orders_by_views_14_days__te_laplace", + "orders_by_clicks_laplace_1day", + "orders_by_views_laplace_28day", + "orders_by_views_laplace_7day", + "orders_by_views_laplace_3day", + "orders_by_clicks_laplace_5day", + "clicks_by_views_laplace_1day", + "clicks_by_views_laplace_5day", + "orders_by_views_laplace_56day", + "orders_by_clicks_laplace_28day", + "orders_by_clicks_laplace_3day", + "orders_by_views_laplace_1day", + "clicks_by_views_laplace_7day", + "clicks_by_views_laplace_28day", + "orders_by_clicks_laplace_56day", + "orders_by_clicks_laplace_7day", + "orders_by_views_laplace_5day", + "clicks_by_views_laplace_56day", + "clicks_by_views_laplace_3day", + "catalog__platform_carts_3_days__te_log", + "catalog__platform_carts_1_days__te_log", + "catalog__platform_carts_14_days__te_log", + "catalog__no_by_go_56_days", + "gross_orders", + "net_orders", + "catalog__per_return", + "cancellations", + "catalog__nqd_56_days", + "catalog__nqd_90_days", + "catalog__per_qr_return", + "catalog__avg_rating", + "catalog__no_by_go_7_days", + "catalog__no_by_go_28_days", + "catalog__no_by_go_90_days", + "search__sale_discount_factor_1", + "search__sale_discount_factor_2", + "clp__sale_discount_factor_2", + "clp__sale_discount_factor_1", + "pdp__sale_discount_factor_2", + "pdp__sale_discount_factor_1", + "ads_predicted_obyc_new_catalogs", + "ads_ds_predicted_target_roi_v1", + "ads_product_predicted_target_roi_v1", + "shipped_rto_rate_6m", + "shipped_rto_rate_3m", + "rate_6m", + "rate_6m", + "rate_3m", + "catalog__search_orders_by_clicks_28_days_percentile", + "catalog__search_clicks_by_views_28_days_percentile", + "catalog__search_views_3_days__te_log", + "predicted_net_orders_by_gross_orders", + "predicted_net_orders_by_gross_orders_smoothened_calibrated", + "predicted_net_orders_by_gross_orders_smoothened", + "views_3day", + "views_28day", + "orders_28day", + "clicks_5day", + "te_cbyv_7day", + "te_obyv_7day", + "te_obyv_3day", + "orders_5day", + "te_obyv_3day", + "te_obyc_7day", + "clicks_28day", + "clicks_1day", + "te_cbyv_3day", + "te_obyc_28day", + "te_cbyv_3day", + "clicks_56day", + "orders_56day", + "views_56", + "te_cbyv_56", + "rated_orders_sscat_percentile", + "views_7day", + "rated_orders_sscat_percentile_bin", + "orders_1day", + "views_56day", + "orders_1day", + "clicks_28day", + "te_cbyv_28day", + "orders_5day", + "max_price_sscat_percentile", + "te_obyc_56day", + "clicks_1day", + "rating", + "te_cbyv_28day", + "clicks_5day", + "te_obyc_56", + "te_obyv_56day", + "views_28day", + "views_1day", + "clicks_56day", + "te_obyc_5day", + "te_obyv_56", + "te_obyc_28day", + "te_cbyv_56", + "te_cbyv_56day", + "views_7day", + "te_obyc_3day", + "te_obyc_1day", + "max_price_sscat_percentile_bin", + "orders_56", + "te_cbyv_7day", + "clicks_7day", + "te_obyv_5day", + "orders_3day", + "te_obyv_1day", + "te_cbyv_5day", + "views_1day", + "te_cbyv_5day", + "te_cbyv_1day", + "min_price_sscat_percentile_bin", + "views_5day", + "clicks_3day", + "te_obyc_56", + "orders_56", + "orders_7day", + "te_obyv_5day", + "min_price_sscat_percentile", + "te_obyv_1day", + "te_obyv_56", + "te_cbyv_1day", + "clicks_56", + "te_obyv_56day", + "te_obyv_28day", + "te_obyv_28day", + "views_56day", + "clicks_56", + "views_5day", + "orders_28day", + "views_3day", + "views_56", + "te_obyc_3day", + "orders_3day", + "te_obyc_7day", + "orders_7day", + "te_cbyv_56day", + "clicks_3day", + "orders_56day", + "te_obyv_7day", + "te_obyc_5day", + "clicks_7day", + "te_obyc_1day", + "te_obyc_56day", + "log_28day", + "log_28day", + "laplace_1day", + "rating_30day", + "diff_asp_arp", + "laplace_7day", + "laplace_28day", + "log_7day", + "log_1day", + "28day", + "log_7day", + "rating_60day", + "log_1day", + "laplace_14day", + "log_7day", + "log_14day", + "log_28day", + "log_28day", + "log_14day", + "log_1day", + "56day", + "laplace_14day", + "laplace_7day", + "log_7day", + "laplace_1day", + "rating_90day", + "asp", + "laplace_28day", + "nqd_boosting_factor_gbm_model_v1", + "nqd_boosting_factor_gbm_model_v0", + "clp_price_aov_boosting_factor_var2", + "clp_price_aov_boosting_factor_var1", + "clp_price_aov_boosting_factor_var4", + "clp_price_aov_boosting_factor_var3", + "loyalty_boosting_factor", + "asp_p70_adj_30day", + "arp_p70_adj_30day", + "orders_by_clicks_bayesian", + "clicks_by_views_bayesian", + "orders_by_views_bayesian", + "orders_by_views_28day", + "clicks_by_views_28day", + "clicks_by_views_7day", + "orders_by_clicks_28day", + "clicks_by_views_3day", + "clicks_by_views_1day", + "clicks_by_views_14day", + "orders_by_views_1day", + "clp_odnr_sale_boosting_factor", + "net_order_by_gross_order", + "net_order_by_gross_order_smoothened", + "clp_odnr_sale_boosting_factor_var2", + "scaledup_boosting_factor", + "vrs_boosting_factor", + "nqd_boosting_factor_analytical_v2", + "search_odnr_sale_boosting_factor", + "nqd_boosting_factor" + ] + } + ], + "keys_schema": [ + "catalog_id" + ], + "keys": [ + { + "cols": [ + "176" + ] + }, + { + "cols": [ + "179" + ] + } + ] +}); + +export default function () { + const res = http.post( + "http://10.138.70.7:8081/retrieve-features", + requestPayload, + { headers: { "Content-Type": "application/json", "Connection": "close" } } + ); + + check(res, { "status is OK": (r) => r.status >= 200 && r.status < 500 }); +} \ No newline at end of file diff --git a/rust-caller-new/proto/retrieve.proto b/rust-caller-new/proto/retrieve.proto index d0574e78..f7af2ab3 100644 --- a/rust-caller-new/proto/retrieve.proto +++ b/rust-caller-new/proto/retrieve.proto @@ -12,7 +12,6 @@ message Query { repeated FeatureGroup feature_groups = 2; repeated string keys_schema = 3; repeated Keys keys = 4; - map metadata = 5; } message Feature { diff --git a/rust-caller-new/src/main.rs b/rust-caller-new/src/main.rs index cabeda95..65651df5 100644 --- a/rust-caller-new/src/main.rs +++ b/rust-caller-new/src/main.rs @@ -1,125 +1,299 @@ -use axum::{ - extract::State, - http::StatusCode, - response::Json, - routing::post, - Router, -}; -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, str::FromStr, sync::Arc}; -use tonic::{metadata::MetadataValue, transport::Channel}; -use tower_http::cors::CorsLayer; +use axum::{extract::State, http::StatusCode, response::Json, routing::post, Router}; +use std::sync::Arc; +use std::time::Duration; +use tokio::signal; +use tokio::sync::Mutex; +use tonic::{metadata::AsciiMetadataValue}; +use clap::Parser; +use http::Uri; pub mod retrieve { tonic::include_proto!("retrieve"); } - use retrieve::feature_service_client::FeatureServiceClient as RetrieveClient; -use retrieve::{FeatureGroup, Keys, Query}; - -#[derive(Serialize, Deserialize)] -struct ApiResponse { - success: bool, - data: Option, - error: Option, - message: String, +use retrieve::{FeatureGroup, Keys, Result as RetrieveResult}; +use serde::{Deserialize, Serialize}; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Server address (must support HTTP/3/QUIC) + #[arg(short, long, default_value = "https://online-feature-store-api.int.meesho.int:443")] + server: String, } -#[derive(Clone)] -struct AppState { - client: RetrieveClient, +// Response structure matching Go's response format +// Note: RetrieveResult is a protobuf type, so we serialize it manually +#[derive(Serialize)] +struct RetrieveFeaturesResponse { + status: String, + #[serde(serialize_with = "serialize_protobuf_result")] + response: RetrieveResult, } -async fn retrieve_features(State(state): State>) - -> Result, (StatusCode, Json)> +// Helper function to serialize protobuf Result +fn serialize_protobuf_result(result: &RetrieveResult, serializer: S) -> Result +where + S: serde::Serializer, { - let client = state.client.clone(); - - // Hardcoded auth metadata - let auth_token = "atishay".to_string(); - let caller_id = "test-3".to_string(); - - match retrieve_features_internal(client, auth_token, caller_id).await { - Ok(result) => Ok(Json(ApiResponse { - success: true, - data: Some(format!("{:?}", result)), - error: None, - message: "Features retrieved successfully".to_string(), - })), - Err(e) => { - println!("āŒ gRPC Error: {}", e); - Err(( - StatusCode::INTERNAL_SERVER_ERROR, - Json(ApiResponse { - success: false, - data: None, - error: Some(e.to_string()), - message: "Failed to retrieve features".to_string(), - }), - )) + // Convert protobuf to JSON bytes and serialize + use prost::Message; + let bytes = result.encode_to_vec(); + serializer.serialize_bytes(&bytes) +} + +// Request body structure for retrieve_features endpoint +#[derive(Debug, Deserialize)] +struct RetrieveFeaturesRequest { + entity_label: String, + feature_groups: Vec, + keys_schema: Vec, + keys: Vec, +} + +#[derive(Debug, Deserialize)] +struct FeatureGroupRequest { + label: String, + feature_labels: Vec, +} + +#[derive(Debug, Deserialize)] +struct KeysRequest { + cols: Vec, +} + +struct AppState { + client: Arc>>>, + auth_token: AsciiMetadataValue, + caller_id: AsciiMetadataValue, +} + +async fn retrieve_features( + State(state): State>, + Json(request_body): Json, +) -> Result, StatusCode> { + // Convert request body to protobuf Query + let mut feature_groups = Vec::new(); + for fg in request_body.feature_groups { + feature_groups.push(FeatureGroup { + label: fg.label, + feature_labels: fg.feature_labels, + }); + } + + let mut keys = Vec::new(); + for k in request_body.keys { + keys.push(Keys { cols: k.cols }); + } + + let query = retrieve::Query { + entity_label: request_body.entity_label, + feature_groups, + keys_schema: request_body.keys_schema, + keys, + }; + let mut request = tonic::Request::new(query); + request.set_timeout(Duration::from_secs(5)); + request.metadata_mut().insert("online-feature-store-auth-token", state.auth_token.clone()); + request.metadata_mut().insert("online-feature-store-caller-id", state.caller_id.clone()); + + // Get mutable access to the client via Mutex + let mut client = state.client.lock().await; + let result = client.retrieve_features(request).await; + + match result { + Ok(response) => { + let result = response.into_inner(); + Ok(Json(RetrieveFeaturesResponse { + status: "success".to_string(), + response: result, + })) } + Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR), } } -async fn retrieve_features_internal( - mut client: RetrieveClient, - auth_token: String, - caller_id: String, -) -> Result> { - println!("Retrieving features..."); - - let mut request = tonic::Request::new(Query { - entity_label: "catalog".to_string(), - feature_groups: vec![ - FeatureGroup { - label: "derived_fp32".to_string(), - feature_labels: vec![ - "clicks_by_views_3_days".to_string(), - ], - }, - ], - keys_schema: vec!["catalog_id".to_string()], - keys: vec![ - Keys { cols: vec!["176".to_string()] }, - Keys { cols: vec!["179".to_string()] }, - ], - metadata: HashMap::new(), - }); - - request.metadata_mut().insert( - "online-feature-store-auth-token", - MetadataValue::from_str(&auth_token)?, - ); - request.metadata_mut().insert( - "online-feature-store-caller-id", - MetadataValue::from_str(&caller_id)?, - ); - - let response = client.retrieve_features(request).await?; - Ok(response.into_inner()) +// Create HTTP/3 gRPC channel using tonic-h3 +// +// Key benefits of HTTP/3: +// 1. Reduced latency: 0-RTT connection establishment vs 2-3 RTT for HTTP/2 +// 2. No head-of-line blocking: Independent QUIC streams vs TCP blocking +// 3. Connection migration: Seamless network transitions +// 4. Better packet loss handling: 60% better latency under 3% packet loss +// 5. Enhanced security: Encrypted headers, mandatory TLS 1.3 +// +// Implementation uses tonic-h3 library (https://github.com/youyuanwu/tonic-h3) +// which provides experimental gRPC over HTTP/3 support using QUIC +async fn create_channel(server: &str) -> Result, Box> { + // Use quinn types directly as shown in tonic-h3 test examples + // See: https://github.com/youyuanwu/tonic-h3 + use quinn::{ClientConfig, Endpoint}; + use quinn::crypto::rustls::QuicClientConfig; + use rustls::{pki_types::CertificateDer, ClientConfig as RustlsClientConfig, RootCertStore}; + use std::net::SocketAddr; + + println!("šŸš€ Using HTTP/3 (QUIC) via tonic-h3"); + println!(" Benefits: 0-RTT, no head-of-line blocking, connection migration"); + println!(" Note: Server must support HTTP/3/QUIC"); + + // Parse server URI + let uri: Uri = server.parse()?; + let host = uri.host().ok_or("Invalid server URI: missing host")?; + let port = uri.port_u16().unwrap_or(443); // Default to 443 for HTTPS/QUIC + + // Create QUIC client configuration with TLS + let mut root_store = RootCertStore::empty(); + // Load system certificates - convert Certificate to CertificateDer + for cert in rustls_native_certs::load_native_certs()? { + root_store.add(CertificateDer::from(cert.0))?; + } + + // Build rustls client config (rustls 0.23 API) + let rustls_config = RustlsClientConfig::builder() + .with_root_certificates(root_store) + .with_no_client_auth(); + + // Create quinn ClientConfig using rustls crypto (as shown in test examples) + let quic_client_config = ClientConfig::new(Arc::new( + QuicClientConfig::try_from(Arc::new(rustls_config))? + )); + + // Create QUIC endpoint with client configuration + // Use quinn::Endpoint directly (as in test examples) + let mut client_endpoint = Endpoint::client(SocketAddr::from(([0, 0, 0, 0], 0)))?; + client_endpoint.set_default_client_config(quic_client_config); + + // Build the full URI for gRPC (QUIC requires HTTPS) + let grpc_uri = if server.starts_with("http://") { + format!("https://{}:{}", host, port) + } else { + server.to_string() + }; + + let grpc_uri: Uri = grpc_uri.parse()?; + + // Create HTTP/3 channel using tonic-h3 + // Based on actual source code from tonic-h3-tests/examples/client.rs + // 1. Create H3QuinnConnector (re-exported from tonic_h3::quinn) + // 2. Create H3Channel from the connector + // Convert quinn::Endpoint to h3_quinn::quinn::Endpoint for the connector + // h3-quinn wraps quinn, so we need to use h3-quinn's endpoint type + use h3_quinn::quinn::Endpoint as H3Endpoint; + + // Create h3-quinn endpoint from quinn endpoint + // The types are compatible since h3-quinn wraps quinn + let h3_endpoint: H3Endpoint = unsafe { std::mem::transmute(client_endpoint) }; + + let server_name = host.to_string(); + // H3QuinnConnector is re-exported from tonic_h3::quinn (which re-exports h3_util::quinn) + let connector = tonic_h3::quinn::H3QuinnConnector::new(grpc_uri.clone(), server_name, h3_endpoint.clone()); + let channel = tonic_h3::H3Channel::new(connector, grpc_uri.clone()); + + println!("āœ… HTTP/3 channel created successfully"); + println!(" Server URI: {}", grpc_uri); + println!(" āš ļø If connection fails, ensure server supports HTTP/3/QUIC"); + + Ok(channel) } -#[tokio::main] +#[tokio::main(flavor = "multi_thread")] async fn main() -> Result<(), Box> { - println!("Connecting to feature store..."); + // Initialize rustls crypto provider (required for rustls 0.23) + // This must be called before any rustls operations + let _ = rustls::crypto::ring::default_provider().install_default(); + + let args = Args::parse(); + + println!("Starting rust-caller with HTTP/3 (QUIC)..."); - let channel = Channel::from_static("http://online-feature-store-api.int.meesho.int:80") - .connect() - .await?; + // Create HTTP/3 gRPC channel using tonic-h3 + let channel = create_channel(&args.server).await?; + // Create gRPC client with the HTTP/3 channel let client = RetrieveClient::new(channel); - let state = Arc::new(AppState { client }); + println!("āœ… Created gRPC connection using HTTP/3 (QUIC)"); + let state = Arc::new(AppState { + client: Arc::new(Mutex::new(client)), + auth_token: AsciiMetadataValue::from_static("atishay"), + caller_id: AsciiMetadataValue::from_static("test-3"), + }); + let app = Router::new() - .route("/retrieve-features", post(retrieve_features)) - .with_state(state) - .layer(CorsLayer::permissive()); - - println!("Starting rust-caller-new on http://0.0.0.0:8080"); + .route("/retrieve-features", post(retrieve_features)); + let app = app.with_state(state); + + // Configure TCP listener for high concurrency let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?; - axum::serve(listener, app).await?; + println!("šŸš€ Rust gRPC Client running on http://0.0.0.0:8080"); + println!("Configured for high performance:"); + println!(" - Protocol: HTTP/3 (QUIC)"); + println!(" - Single gRPC connection"); + println!(" - Tokio runtime using all CPU cores"); + println!(" - HTTP/3 over QUIC (UDP-based, independent streams)"); + println!(" - No head-of-line blocking"); + println!(" - Connection migration support"); + println!(" - Enhanced packet loss handling"); + println!(" - 0-RTT connection establishment"); + println!(" - Encrypted headers (TLS 1.3)"); + println!("\nāš ļø Note: Server must support HTTP/3/QUIC"); + println!("šŸ“Š For performance details, see HTTP3_BENEFITS.md"); + + // Create shutdown signal handler + let shutdown_signal = async { + let ctrl_c = async { + signal::ctrl_c() + .await + .expect("failed to install Ctrl+C handler"); + }; + #[cfg(unix)] + let terminate = async { + signal::unix::signal(signal::unix::SignalKind::terminate()) + .expect("failed to install signal handler") + .recv() + .await; + }; + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + tokio::select! { + _ = ctrl_c => {}, + _ = terminate => {}, + } + println!("\nShutting down server..."); + }; + + // Start server in background task + let server_handle = tokio::spawn(async move { + if let Err(e) = axum::serve(listener, app).await { + eprintln!("Server error: {}", e); + } + }); + + // Wait for shutdown signal + shutdown_signal.await; + + // Graceful shutdown with timeout (similar to go-caller's 5 second timeout) + println!("Waiting for in-flight requests to complete..."); + let shutdown_timeout = tokio::time::sleep(Duration::from_secs(5)); + let abort_handle = server_handle.abort_handle(); + + tokio::select! { + result = server_handle => { + match result { + Ok(_) => println!("Server stopped gracefully"), + Err(e) => eprintln!("Server task error: {}", e), + } + } + _ = shutdown_timeout => { + println!("Shutdown timeout reached, forcing shutdown"); + abort_handle.abort(); + // Wait a bit for abort to complete + tokio::time::sleep(Duration::from_millis(100)).await; + } + } + + // Channel will be closed when dropped + println!("Server exited"); Ok(()) } - -