From 4e53510f411bc3d8a09aa90b47dce5a2d6e6cc49 Mon Sep 17 00:00:00 2001 From: turtleDev Date: Wed, 4 Sep 2024 17:04:47 +0530 Subject: [PATCH] chore: remove client example --- example/example.proto | 7 --- example/main.go | 70 --------------------- example/readme.md | 104 ------------------------------- example/sample.pb.go | 142 ------------------------------------------ 4 files changed, 323 deletions(-) delete mode 100644 example/example.proto delete mode 100644 example/main.go delete mode 100644 example/readme.md delete mode 100644 example/sample.pb.go diff --git a/example/example.proto b/example/example.proto deleted file mode 100644 index 2312eb9e..00000000 --- a/example/example.proto +++ /dev/null @@ -1,7 +0,0 @@ -syntax = "proto3"; - -package raystack.raccoon; - -message SampleEvent { - string description = 1; -} diff --git a/example/main.go b/example/main.go deleted file mode 100644 index ace2d210..00000000 --- a/example/main.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "time" - - "github.com/gorilla/websocket" - pb "github.com/raystack/raccoon/proto" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -var ( - url = "ws://localhost:8080/api/v1/events" - header = http.Header{ - "X-User-ID": []string{"1234"}, - } - pingInterval = 5 * time.Second -) - -func main() { - ws, _, err := websocket.DefaultDialer.Dial(url, header) - if err != nil { - panic("Fail to make websocket connection") - } - // Gorilla websocket has default PingHandler which sends Pong. No need to explicitly heandle it. - go pinger(ws) - - event1 := generateSampleEvent() - event2 := generateSampleEvent() - eventBatch := []*pb.Event{ - event1, - event2, - } - - sentTime := time.Now() - request := &pb.SendEventRequest{ - ReqGuid: "55F648D1-9A73-4F6C-8657-4D26A6C1F168", - SentTime: ×tamppb.Timestamp{ - Seconds: sentTime.Unix(), - Nanos: int32(sentTime.Nanosecond()), - }, - Events: eventBatch, - } - reqBin, _ := proto.Marshal(request) - ws.WriteMessage(websocket.BinaryMessage, reqBin) - - _, response, _ := ws.ReadMessage() - SendEventResponse := &pb.SendEventResponse{} - proto.Unmarshal(response, SendEventResponse) - // Handle the response accordingly - fmt.Printf("%v", SendEventResponse) -} - -func generateSampleEvent() *pb.Event { - sampleEvent := &SampleEvent{Description: "user_click"} - sampleBin, _ := proto.Marshal(sampleEvent) - event := &pb.Event{EventBytes: sampleBin, Type: "some-type"} - return event -} - -func pinger(ws *websocket.Conn) { - ticker := time.Tick(pingInterval) - for { - <-ticker - ws.WriteControl(websocket.PingMessage, []byte("--ping--"), time.Now().Add(pingInterval)) - fmt.Println("ping") - } -} diff --git a/example/readme.md b/example/readme.md deleted file mode 100644 index b58bdc24..00000000 --- a/example/readme.md +++ /dev/null @@ -1,104 +0,0 @@ -There are couple of things the client to handle to start send events to Raccoon. - -- [Establish Websocket Connection](#establish-websocket-connection) -- [Set Ping/Pong Handler](#set-pingpong-handler) -- [Batch Events](#batch-events) -- [Send The Batch](#send-the-batch) -- [Handle The Response](#handle-the-response) - -Below are the explanation of sample client in [main.go](https://github.com/raystack/raccoon/tree/main/docs/example/main.go) - -## Establish Websocket Connection - -You are free to use any websocket client as long as it supports passing header. You can connect to `/api/v1/events` endpoint with uniq id header set. You'll also need to handle retry in case Raccon reject the connection because [max connection is reached](). - -```go -var ( - url = "ws://localhost:8080/api/v1/events" - header = http.Header{ - "X-User-ID": []string{"1234"}, - } -) - -func main() { - ws, _, err := websocket.DefaultDialer.Dial(url, header) - if err != nil { - panic("Fail to make websocket connection") - } -``` - -## Set Ping/Pong Handler - -Raccoon needs to maintain many alive connections. To clean up dead connection, Raccoon will close client that couldn't response to Ping on time. Because of that, the client need to handle Ping if not handled by the websocket client. - -```go - // Gorilla websocket has default PingHandler which sends Pong. No need to explicitly heandle it. - go pinger(ws) -``` - -You can also check the liveliness of the server by having Pinger function and close the connection if necessary - -```go -func pinger(ws *websocket.Conn) { - ticker := time.Tick(pingInterval) - for { - <-ticker - ws.WriteControl(websocket.PingMessage, []byte("--ping--"), time.Now().Add(pingInterval)) - fmt.Println("ping") - } -} -``` - -## Batch Events - -When the connection is set, all you need to do is collect the event and send them in batch. - -```go - event1 := generateSampleEvent() - event2 := generateSampleEvent() - eventBatch := []*pb.Event{ - event1, - event2, - } -``` - -Where `generateSampleEvent` is - -```go -func generateSampleEvent() *pb.Event { - sampleEvent := &SampleEvent{Description: "user_click"} - sampleBin, _ := proto.Marshal(sampleEvent) - event := &pb.Event{EventBytes: sampleBin, Type: "some-type"} - return event -} -``` - -## Send The Batch - -Now you have websocket connection and batch of event ready, all you need is send the batch. Don't forget to fill `send_time` field before sending the request. - -```go - sentTime := time.Now() - request := &pb.SendEventRequest{ - ReqGuid: "55F648D1-9A73-4F6C-8657-4D26A6C1F168", - SentTime: ×tamppb.Timestamp{ - Seconds: sentTime.Unix(), - Nanos: int32(sentTime.Nanosecond()), - }, - Events: eventBatch, - } - reqBin, _ := proto.Marshal(request) - ws.WriteMessage(websocket.BinaryMessage, reqBin) -``` - -## Handle The Response - -Raccoon sends SendEventResponse for every batch of events sent from the client. The ReqGuid in the response identifies the batch that the client sent. The response object could be used for client's telemetry in terms of how may batches succeeded, failed etc., The clients can retry based on failures however server side kafka send failures are not sent as failures due to the [acknowledgement design as explained here](https://github.com/raystack/raccoon/blob/main/docs/concepts/architecture.md#acknowledging-events). - -```go - _, response, _ := ws.ReadMessage() - SendEventResponse := &pb.SendEventResponse{} - proto.Unmarshal(response, SendEventResponse) - // Handle the response accordingly - fmt.Printf("%v", SendEventResponse) -``` diff --git a/example/sample.pb.go b/example/sample.pb.go deleted file mode 100644 index 97e79a34..00000000 --- a/example/sample.pb.go +++ /dev/null @@ -1,142 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0-rc.1 -// protoc v3.14.0 -// source: example.proto - -package main - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type SampleEvent struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` -} - -func (x *SampleEvent) Reset() { - *x = SampleEvent{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SampleEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SampleEvent) ProtoMessage() {} - -func (x *SampleEvent) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SampleEvent.ProtoReflect.Descriptor instead. -func (*SampleEvent) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0} -} - -func (x *SampleEvent) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -var File_example_proto protoreflect.FileDescriptor - -var file_example_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x0c, 0x6f, 0x64, 0x70, 0x66, 0x2e, 0x72, 0x61, 0x63, 0x63, 0x6f, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, - 0x0b, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_example_proto_rawDescOnce sync.Once - file_example_proto_rawDescData = file_example_proto_rawDesc -) - -func file_example_proto_rawDescGZIP() []byte { - file_example_proto_rawDescOnce.Do(func() { - file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData) - }) - return file_example_proto_rawDescData -} - -var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_example_proto_goTypes = []interface{}{ - (*SampleEvent)(nil), // 0: raystack.raccoon.SampleEvent -} -var file_example_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_example_proto_init() } -func file_example_proto_init() { - if File_example_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SampleEvent); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_example_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_example_proto_goTypes, - DependencyIndexes: file_example_proto_depIdxs, - MessageInfos: file_example_proto_msgTypes, - }.Build() - File_example_proto = out.File - file_example_proto_rawDesc = nil - file_example_proto_goTypes = nil - file_example_proto_depIdxs = nil -}