paint-brush
gRPC-সিক্রেট: সময়সীমা, সময়সীমা, এবং কাস্টম প্রসঙ্গ আয়ত্ত করাদ্বারা@gultm
888 পড়া
888 পড়া

gRPC-সিক্রেট: সময়সীমা, সময়সীমা, এবং কাস্টম প্রসঙ্গ আয়ত্ত করা

দ্বারা Tatyana9m2024/08/01
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

gRPC হল একটি ওপেন সোর্স রিমোট প্রসিডিওর কল (RPC) ফ্রেমওয়ার্ক। এটি পরিষেবাগুলির মধ্যে দক্ষ এবং মাপযোগ্য যোগাযোগ সক্ষম করে। একটি গুরুত্বপূর্ণ দিক হল সময়সীমার ব্যবস্থাপনা, অনুরোধের সময়সীমা, এবং প্রসঙ্গ প্রচার করা। এই প্রক্রিয়াগুলি বোঝা পরিষেবাগুলি অবিলম্বে সাড়া দেয় তা নিশ্চিত করতে সহায়তা করে৷
featured image - gRPC-সিক্রেট: সময়সীমা, সময়সীমা, এবং কাস্টম প্রসঙ্গ আয়ত্ত করা
Tatyana HackerNoon profile picture

gRPC, একটি ওপেন-সোর্স রিমোট প্রসিডিওর কল (RPC) ফ্রেমওয়ার্ক, পরিষেবাগুলির মধ্যে দক্ষ এবং মাপযোগ্য যোগাযোগ সক্ষম করে। জিআরপিসির একটি গুরুত্বপূর্ণ দিক হল সময়সীমার ব্যবস্থাপনা, অনুরোধের সময়সীমা, এবং কাস্টম কাঠামো সহ প্রসঙ্গ প্রচার করা।


এই প্রক্রিয়াগুলি বোঝা নিশ্চিত করতে সাহায্য করে যে পরিষেবাগুলি অবিলম্বে সাড়া দেয়, একটি যুক্তিসঙ্গত সময়সীমা অতিক্রম করে এমন ক্রিয়াকলাপগুলিতে সংস্থানগুলি নষ্ট হয় না এবং কাস্টম মেটাডেটা কার্যকরভাবে প্রেরণ করা হয়।

সময়সীমা এবং অনুরোধের সময়সীমা বোঝা

সময়সীমা

জিআরপিসি-তে একটি সময়সীমা সর্বাধিক সময় নির্দিষ্ট করে যার মধ্যে একটি অপারেশন সম্পূর্ণ করতে হবে। এই সময়সীমার মধ্যে অপারেশন সম্পন্ন না হলে, এটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে। অপ্রতিক্রিয়াশীল বা ধীর পরিষেবার কারণে সিস্টেম সংস্থানগুলি অনির্দিষ্টকালের জন্য বাঁধা না হয় তা নিশ্চিত করার জন্য সময়সীমা অপরিহার্য।

সময়সীমার অনুরোধ করুন

একটি অনুরোধের সময়সীমা এমন একটি সময়কাল যা একজন ক্লায়েন্ট সার্ভার থেকে একটি প্রতিক্রিয়ার জন্য অপেক্ষা করতে ইচ্ছুক। এই সময়ের মধ্যে সার্ভার সাড়া না দিলে, অনুরোধটি বাতিল করা হয়। এই প্রক্রিয়াটি ক্লায়েন্টকে একটি প্রতিক্রিয়ার জন্য অনির্দিষ্টকালের জন্য অপেক্ষা করা থেকে রক্ষা করে।

gRPC-তে সময়সীমা এবং অনুরোধের সময়সীমা সেট করা

ক্লায়েন্ট এবং সার্ভার উভয় দিকেই সময়সীমা নির্ধারণ এবং সময়সীমার অনুরোধ করার জন্য gRPC নমনীয় বিকল্প সরবরাহ করে। আপনি Go এ কীভাবে এটি করতে পারেন তা এখানে:

ক্লায়েন্ট-সাইড সেটিংয়ের সময়সীমা


 import ( "context" "log" "time" "google.golang.org/grpc" pb "path/to/your/protobuf/package" ) func main() { conn, err := grpc.Dial("server_address", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewYourServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err := client.YourMethod(ctx, &pb.YourRequest{}) if err != nil { log.Fatalf("could not call method: %v", err) } log.Printf("Response: %v", resp) }

সার্ভার-সাইড হ্যান্ডলিং

সার্ভারের দিকে, gRPC আপনাকে সময়সীমা কার্যকর করতে এবং ক্লায়েন্ট-নির্দিষ্ট সময়সীমা অতিক্রম করার পরিস্থিতিগুলি পরিচালনা করতে দেয়:


 import ( "context" "log" "net" "time" "google.golang.org/grpc" pb "path/to/your/protobuf/package" ) type server struct { pb.UnimplementedYourServiceServer } func (s *server) YourMethod(ctx context.Context, req *pb.YourRequest) (*pb.YourResponse, error) { select { case <-time.After(10 * time.Second): return &pb.YourResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } } func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterYourServiceServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }


প্রেক্ষাপটে কাস্টম স্ট্রাকচার প্রচার করা

জিআরপিসি-তে কনটেক্সট এর মাধ্যমে কাস্টম স্ট্রাকচার পাঠানোর জন্য, আপনাকে প্রেক্ষাপটে ডেটা সংযুক্ত করার আগে সিরিয়ালাইজ করতে হবে এবং তারপর রিসিভিং এন্ডে ডিসিরিয়ালাইজ করতে হবে। এতে আপনার কাস্টম স্ট্রাকচারগুলিকে এমন একটি বিন্যাসে রূপান্তর করা জড়িত যা নেটওয়ার্কের মাধ্যমে প্রেরণ করা যেতে পারে, যেমন JSON বা প্রোটোকল বাফার, এবং তারপরে প্রসঙ্গ মেটাডেটাতে এই সিরিয়ালাইজড ডেটা যোগ করা।

ধাপে ধাপে প্রক্রিয়া

  1. আপনার কাস্টম কাঠামো সংজ্ঞায়িত করুন : আপনি যে কাস্টম কাঠামো পাঠাতে চান তা সংজ্ঞায়িত করুন।
  2. স্ট্রাকচারকে সিরিয়ালাইজ করুন : কাস্টম স্ট্রাকচারটিকে একটি স্ট্রিং বা বাইট অ্যারেতে রূপান্তর করুন।
  3. প্রসঙ্গে সংযুক্ত করুন : প্রসঙ্গ মেটাডেটাতে সিরিয়ালাইজড ডেটা যোগ করুন।
  4. ট্রান্সমিট : প্রসঙ্গ সহ gRPC কল পাঠান।
  5. সার্ভারে এক্সট্র্যাক্ট এবং ডিসিরিয়ালাইজ করুন : সার্ভার সাইডের প্রসঙ্গ থেকে মেটাডেটা বের করুন এবং কাস্টম স্ট্রাকচারে আবার ডিসিরিয়ালাইজ করুন।

ধাপ 1: আপনার কাস্টম কাঠামো সংজ্ঞায়িত করুন


 type CustomStruct struct { Field1 string Field2 int }


ধাপ 2: স্ট্রাকচার সিরিয়ালাইজ করুন


 import ( "context" "encoding/json" "fmt" "google.golang.org/grpc/metadata" ) func serializeCustomStruct(customStruct CustomStruct) (string, error) { data, err := json.Marshal(customStruct) if err != nil { return "", err } return string(data), nil }


ধাপ 3: প্রসঙ্গে সংযুক্ত করুন


 func attachCustomStructToContext(ctx context.Context, customStruct CustomStruct) (context.Context, error) { serializedData, err := serializeCustomStruct(customStruct) if err != nil { return nil, err } md := metadata.Pairs("custom-struct", serializedData) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, nil }


ধাপ 4: প্রেরণ


 func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewYourServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() customStruct := CustomStruct{Field1: "value1", Field2: 42} ctx, err = attachCustomStructToContext(ctx, customStruct) if err != nil { log.Fatalf("could not attach custom struct to context: %v", err) } resp, err := client.YourMethod(ctx, &pb.YourRequest{}) if err != nil { log.Fatalf("could not call method: %v", err) } log.Printf("Response: %v", resp) }


ধাপ 5: সার্ভারে এক্সট্র্যাক্ট এবং ডিসিরিয়ালাইজ করুন


 func deserializeCustomStruct(data string) (CustomStruct, error) { var customStruct CustomStruct err := json.Unmarshal([]byte(data), &customStruct) if err != nil { return CustomStruct{}, err } return customStruct, nil } func extractCustomStructFromContext(ctx context.Context) (CustomStruct, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return CustomStruct{}, fmt.Errorf("no metadata found in context") } serializedData := md["custom-struct"] if len(serializedData) == 0 { return CustomStruct{}, fmt.Errorf("no custom struct found in metadata") } return deserializeCustomStruct(serializedData[0]) } func (s *server) YourMethod(ctx context.Context, req *pb.YourRequest) (*pb.YourResponse, error) { customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return nil, err } log.Printf("Received custom struct: %+v", customStruct) select { case <-time.After(10 * time.Second): return &pb.YourResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } }


সমস্ত জিআরপিসি কলের জন্য মিডলওয়্যার বাস্তবায়ন করা

কাস্টম স্ট্রাকচার সহ প্রসঙ্গ প্রচার পরিচালনা করতে, ধারাবাহিকভাবে সমস্ত gRPC কল জুড়ে, আপনি ইন্টারসেপ্টর ব্যবহার করতে পারেন। ইন্টারসেপ্টর হল মিডলওয়্যার যা অনুরোধ এবং প্রতিক্রিয়া প্রক্রিয়া করে, লগিং, মনিটরিং এবং প্রসঙ্গ মেটাডেটা হ্যান্ডলিং এর মতো কার্যকারিতা যোগ করে।

ইউনারি এবং স্ট্রিমিং ইন্টারসেপ্টর

বিভিন্ন ধরনের RPC কল পরিচালনা করতে আপনার ইউনারী এবং স্ট্রিমিং ইন্টারসেপ্টর উভয়েরই প্রয়োজন:


  • ইউনারি ইন্টারসেপ্টর : একক অনুরোধ-প্রতিক্রিয়া চক্র পরিচালনা করুন।


  • স্ট্রিমিং ইন্টারসেপ্টর : ক্লায়েন্ট-সাইড স্ট্রিমিং, সার্ভার-সাইড স্ট্রিমিং এবং দ্বিমুখী স্ট্রিমিং সহ অনুরোধ এবং প্রতিক্রিয়াগুলির স্ট্রিমগুলি পরিচালনা করুন।

ইউনারি ইন্টারসেপ্টর ইমপ্লিমেন্টেশন

ক্লায়েন্ট-সাইড ইউনারি ইন্টারসেপ্টর:


 func unaryClientInterceptor( ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption, ) error { customStruct, ok := ctx.Value("customStruct").(CustomStruct) if ok { ctx, err := attachCustomStructToContext(ctx, customStruct) if err != nil { return err } } return invoker(ctx, method, req, reply, cc, opts...) }


সার্ভার-সাইড ইউনারি ইন্টারসেপ্টর:


 func unaryServerInterceptor( ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (interface{}, error) { customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return nil, err } ctx = context.WithValue(ctx, "customStruct", customStruct) return handler(ctx, req) }

স্ট্রিমিং ইন্টারসেপ্টর বাস্তবায়ন

ক্লায়েন্ট-সাইড স্ট্রিমিং ইন্টারসেপ্টর:


 func streamClientInterceptor( ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption, ) (grpc.ClientStream, error) { customStruct, ok := ctx.Value("customStruct").(CustomStruct) if ok { ctx, err := attachCustomStructToContext(ctx, customStruct) if err != nil { return nil, err } } return


সার্ভার-সাইড স্ট্রিমিং ইন্টারসেপ্টর:


 import ( "context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // StreamServerInterceptor handles server-side streaming func streamServerInterceptor( srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler, ) error { ctx := ss.Context() customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return err } // Add custom struct to context for server handling newCtx := context.WithValue(ctx, "customStruct", customStruct) wrapped := grpc_middleware.WrapServerStream(ss) wrapped.WrappedContext = newCtx // Handle the request return handler(srv, wrapped) } // Example of using the interceptor in a gRPC server setup func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } // Register the interceptors server := grpc.NewServer( grpc.UnaryInterceptor(unaryServerInterceptor), grpc.StreamInterceptor(streamServerInterceptor), ) // Register your gRPC service implementations here pb.RegisterYourServiceServer(server, &yourServiceServer{}) if err := server.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }


ইউনারি এবং স্ট্রিমিং ইন্টারসেপ্টর তৈরি এবং নিবন্ধন করার মাধ্যমে, আপনি নিশ্চিত করতে পারেন যে কাস্টম স্ট্রাকচার সহ প্রসঙ্গ প্রচার, সমস্ত জিআরপিসি কল জুড়ে ধারাবাহিকভাবে পরিচালনা করা হয়। এই পদ্ধতিটি নিশ্চিত করে যে আপনার কাস্টম মেটাডেটা সঠিকভাবে পরিচালিত এবং প্রচারিত হয়েছে, যা আপনাকে শক্তিশালী এবং নমনীয় gRPC পরিষেবাগুলি তৈরি করতে দেয়।