github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/examples/cluster/echo_service.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/lirm/aeron-go/aeron" 8 "github.com/lirm/aeron-go/aeron/atomic" 9 "github.com/lirm/aeron-go/aeron/idlestrategy" 10 "github.com/lirm/aeron-go/aeron/logbuffer" 11 "github.com/lirm/aeron-go/cluster" 12 "github.com/lirm/aeron-go/cluster/codecs" 13 ) 14 15 type EchoService struct { 16 cluster cluster.Cluster 17 messageCount int32 18 } 19 20 func (s *EchoService) OnStart(cluster cluster.Cluster, image aeron.Image) { 21 s.cluster = cluster 22 if image == nil { 23 fmt.Printf("OnStart with no image\n") 24 } else { 25 cnt := image.Poll(func(buf *atomic.Buffer, offset int32, length int32, hdr *logbuffer.Header) { 26 if length == 4 && s.messageCount == 0 { 27 s.messageCount = buf.GetInt32(offset) 28 } else { 29 fmt.Printf("WARNING: unexpected snapshot message - pos=%d offset=%d length=%d\n", 30 hdr.Position(), offset, length) 31 } 32 }, 100) 33 fmt.Printf("OnStart with image - snapshotMsgCnt=%d messageCount=%d\n", cnt, s.messageCount) 34 } 35 } 36 37 func (s *EchoService) OnSessionOpen(session cluster.ClientSession, timestamp int64) { 38 fmt.Printf("OnSessionOpen - sessionId=%d timestamp=%v\n", session.Id(), timestamp) 39 } 40 41 func (s *EchoService) OnSessionClose( 42 session cluster.ClientSession, 43 timestamp int64, 44 reason codecs.CloseReasonEnum, 45 ) { 46 fmt.Printf("OnSessionClose - sessionId=%d timestamp=%v reason=%v\n", session.Id(), timestamp, reason) 47 } 48 49 func (s *EchoService) OnSessionMessage( 50 session cluster.ClientSession, 51 timestamp int64, 52 buffer *atomic.Buffer, 53 offset int32, 54 length int32, 55 header *logbuffer.Header, 56 ) { 57 s.messageCount++ 58 for offerCnt := 1; ; offerCnt++ { 59 result := session.Offer(buffer, offset, length, nil) 60 if result >= 0 { 61 return 62 } else if result == aeron.BackPressured || result == aeron.AdminAction { 63 s.cluster.IdleStrategy().Idle(0) 64 } else { 65 fmt.Printf("WARNING: OnSessionMessage offer failed - sessionId=%d time=%d pos=%d len=%d offerCnt=%d result=%v\n", 66 session.Id(), timestamp, header.Position(), length, offerCnt, result) 67 } 68 } 69 } 70 71 func (s *EchoService) OnTimerEvent(correlationId, timestamp int64) { 72 fmt.Printf("OnTimerEvent - correlationId=%d timestamp=%v\n", correlationId, timestamp) 73 } 74 75 func (s *EchoService) OnTakeSnapshot(publication *aeron.Publication) { 76 fmt.Printf("OnTakeSnapshot - streamId=%d sessionId=%d messageCount=%d\n", 77 publication.StreamID(), publication.SessionID(), s.messageCount) 78 buf := atomic.MakeBuffer(make([]byte, 4)) 79 buf.PutInt32(0, s.messageCount) 80 for { 81 result := publication.Offer(buf, 0, buf.Capacity(), nil) 82 if result >= 0 { 83 return 84 } else if result == aeron.BackPressured || result == aeron.AdminAction { 85 s.cluster.IdleStrategy().Idle(0) 86 } else { 87 fmt.Printf("WARNING: OnTakeSnapshot offer failed - result=%v\n", result) 88 } 89 } 90 } 91 92 func (s *EchoService) OnRoleChange(role cluster.Role) { 93 fmt.Printf("OnRoleChange - role=%v\n", role) 94 } 95 96 func (s *EchoService) OnTerminate(cluster cluster.Cluster) { 97 fmt.Printf("OnTerminate - role=%v logPos=%d\n", cluster.Role(), cluster.LogPosition()) 98 } 99 100 func (s *EchoService) OnNewLeadershipTermEvent( 101 leadershipTermId int64, 102 logPosition int64, 103 timestamp int64, 104 termBaseLogPosition int64, 105 leaderMemberId int32, 106 logSessionId int32, 107 timeUnit codecs.ClusterTimeUnitEnum, 108 appVersion int32, 109 ) { 110 fmt.Printf("OnNewLeadershipTermEvent - leaderTermId=%d logPos=%d time=%d termBase=%d leaderId=%d logSessionId=%d timeUnit=%v appVer=%d\n", 111 leadershipTermId, logPosition, timestamp, termBaseLogPosition, leaderMemberId, logSessionId, timeUnit, appVersion) 112 } 113 114 func main() { 115 ctx := aeron.NewContext() 116 if aeronDir := os.Getenv("AERON_DIR"); aeronDir != "" { 117 ctx.AeronDir(aeronDir) 118 fmt.Println("aeron dir: ", aeronDir) 119 } else if _, err := os.Stat("/dev/shm"); err == nil { 120 path := fmt.Sprintf("/dev/shm/aeron-%s", aeron.UserName) 121 ctx.AeronDir(path) 122 fmt.Println("aeron dir: ", path) 123 } 124 125 opts := cluster.NewOptions() 126 if idleStr := os.Getenv("NO_OP_IDLE"); idleStr != "" { 127 opts.IdleStrategy = &idlestrategy.Busy{} 128 } 129 if opts.ClusterDir = os.Getenv("CLUSTER_DIR"); opts.ClusterDir == "" { 130 opts.ClusterDir = "/tmp/aeron-go-poc/cluster" 131 } 132 133 service := &EchoService{} 134 agent, err := cluster.NewClusteredServiceAgent(ctx, opts, service) 135 if err != nil { 136 panic(err) 137 } 138 139 if err := agent.StartAndRun(); err != nil { 140 panic(err) 141 } 142 }