github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/aeron/driver/listeneradapter.go (about) 1 /* 2 Copyright 2016-2018 Stanislav Liberman 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package driver 18 19 import ( 20 "strings" 21 22 "github.com/lirm/aeron-go/aeron/logging" 23 24 "github.com/lirm/aeron-go/aeron/atomic" 25 "github.com/lirm/aeron-go/aeron/broadcast" 26 "github.com/lirm/aeron-go/aeron/command" 27 ) 28 29 var logger = logging.MustGetLogger("driver") 30 31 var Events = struct { 32 /** Error Response */ 33 OnError int32 34 /** New subscription Buffer Notification */ 35 OnAvailableImage int32 36 /** New publication Buffer Notification */ 37 OnPublicationReady int32 38 /** Operation Succeeded */ 39 OnOperationSuccess int32 40 /** Inform client of timeout and removal of inactive image */ 41 OnUnavailableImage int32 42 /** New Exclusive Publication Buffer notification */ 43 OnExclusivePublicationReady int32 44 /** New subscription notification */ 45 OnSubscriptionReady int32 46 /** New counter notification */ 47 OnCounterReady int32 48 /** inform clients of removal of counter */ 49 OnUnavailableCounter int32 50 /** inform clients of client timeout */ 51 OnClientTimeout int32 52 }{ 53 0x0F01, 54 0x0F02, 55 0x0F03, 56 0x0F04, 57 0x0F05, 58 0x0F06, 59 0x0F07, 60 0x0F08, 61 0x0F09, 62 0x0F0A, 63 } 64 65 type SubscriberPosition struct { 66 indicatorID int32 67 registrationID int64 68 } 69 70 func (pos *SubscriberPosition) RegistrationID() int64 { 71 return pos.registrationID 72 } 73 74 func (pos *SubscriberPosition) IndicatorID() int32 { 75 return pos.indicatorID 76 } 77 78 type Listener interface { 79 OnNewPublication(streamID int32, sessionID int32, positionLimitCounterID int32, channelStatusIndicatorID int32, 80 logFileName string, correlationID int64, registrationID int64) 81 OnNewExclusivePublication(streamID int32, sessionID int32, positionLimitCounterID int32, channelStatusIndicatorID int32, 82 logFileName string, correlationID int64, registrationID int64) 83 OnAvailableImage(streamID int32, sessionID int32, logFilename string, sourceIdentity string, 84 subscriberPositionID int32, subsRegID int64, correlationID int64) 85 OnUnavailableImage(correlationID int64, subscriptionRegistrationID int64) 86 OnOperationSuccess(correlationID int64) 87 OnErrorResponse(offendingCommandCorrelationID int64, errorCode int32, errorMessage string) 88 OnChannelEndpointError(correlationID int64, errorMessage string) 89 OnSubscriptionReady(correlationID int64, channelStatusIndicatorID int32) 90 OnAvailableCounter(correlationID int64, counterID int32) 91 OnUnavailableCounter(correlationID int64, counterID int32) 92 OnClientTimeout(clientID int64) 93 } 94 95 type ListenerAdapter struct { 96 listener Listener 97 broadcastReceiver *broadcast.CopyReceiver 98 } 99 100 func NewAdapter(driverListener Listener, broadcastReceiver *broadcast.CopyReceiver) *ListenerAdapter { 101 adapter := new(ListenerAdapter) 102 adapter.listener = driverListener 103 adapter.broadcastReceiver = broadcastReceiver 104 105 return adapter 106 } 107 108 func (adapter *ListenerAdapter) ReceiveMessages() int { 109 handler := func(msgTypeID int32, buffer *atomic.Buffer, offset int32, length int32) { 110 logger.Debugf("received %d", msgTypeID) 111 switch int32(msgTypeID) { 112 case Events.OnPublicationReady: 113 logger.Debugf("received ON_PUBLICATION_READY") 114 115 var msg publicationReady 116 msg.Wrap(buffer, int(offset)) 117 118 streamID := msg.streamID.Get() 119 sessionID := msg.sessionID.Get() 120 positionLimitCounterID := msg.publicationLimitOffset.Get() 121 channelStatusIndicatorID := msg.channelStatusIndicatorID.Get() 122 correlationID := msg.correlationID.Get() 123 registrationID := msg.registrationID.Get() 124 logFileName := msg.logFileName.Get() 125 126 adapter.listener.OnNewPublication(streamID, sessionID, positionLimitCounterID, channelStatusIndicatorID, 127 logFileName, correlationID, registrationID) 128 case Events.OnExclusivePublicationReady: 129 logger.Debugf("received ON_EXCLUSIVE_PUBLICATION_READY") 130 131 var msg publicationReady 132 msg.Wrap(buffer, int(offset)) 133 134 streamID := msg.streamID.Get() 135 sessionID := msg.sessionID.Get() 136 positionLimitCounterID := msg.publicationLimitOffset.Get() 137 channelStatusIndicatorID := msg.channelStatusIndicatorID.Get() 138 correlationID := msg.correlationID.Get() 139 registrationID := msg.registrationID.Get() 140 logFileName := msg.logFileName.Get() 141 142 adapter.listener.OnNewExclusivePublication(streamID, sessionID, positionLimitCounterID, channelStatusIndicatorID, 143 logFileName, correlationID, registrationID) 144 case Events.OnSubscriptionReady: 145 logger.Debugf("received ON_SUBSCRIPTION_READY") 146 147 var msg subscriptionReady 148 msg.Wrap(buffer, int(offset)) 149 150 correlationID := msg.correlationID.Get() 151 channelStatusIndicatorID := msg.channelStatusIndicatorID.Get() 152 153 adapter.listener.OnSubscriptionReady(correlationID, channelStatusIndicatorID) 154 case Events.OnAvailableImage: 155 logger.Debugf("received ON_AVAILABLE_IMAGE") 156 157 var header imageReadyHeader 158 header.Wrap(buffer, int(offset)) 159 160 streamID := header.streamID.Get() 161 sessionID := header.sessionID.Get() 162 logFileName := header.logFile.Get() 163 sourceIdentity := header.sourceIdentity.Get() 164 subsPosID := header.subsPosID.Get() 165 subsRegID := header.subsRegistrationID.Get() 166 correlationID := header.correlationID.Get() 167 168 logger.Debugf("logFileName: %v", logFileName) 169 logger.Debugf("sourceIdentity: %v", sourceIdentity) 170 171 adapter.listener.OnAvailableImage(streamID, sessionID, logFileName, sourceIdentity, subsPosID, subsRegID, 172 correlationID) 173 case Events.OnOperationSuccess: 174 logger.Debugf("received ON_OPERATION_SUCCESS") 175 176 var msg command.CorrelatedMessage 177 msg.Wrap(buffer, int(offset)) 178 179 correlationID := msg.CorrelationID.Get() 180 181 adapter.listener.OnOperationSuccess(correlationID) 182 case Events.OnUnavailableImage: 183 logger.Debugf("received ON_UNAVAILABLE_IMAGE") 184 185 var msg command.ImageMessage 186 msg.Wrap(buffer, int(offset)) 187 188 correlationID := msg.CorrelationID.Get() 189 subscriptionRegistrationID := msg.SubscriptionRegistrationID.Get() 190 191 adapter.listener.OnUnavailableImage(correlationID, subscriptionRegistrationID) 192 case Events.OnError: 193 logger.Debugf("received ON_ERROR") 194 195 var msg errorMessage 196 msg.Wrap(buffer, int(offset)) 197 198 if msg.errorCode.Get() == command.ErrorCodeChannelEndpointError || 199 strings.Contains(msg.errorMessage.Get(), "Address already in use") { // hack for c media driver 200 adapter.listener.OnChannelEndpointError(msg.offendingCommandCorrelationID.Get(), msg.errorMessage.Get()) 201 } else { 202 adapter.listener.OnErrorResponse(msg.offendingCommandCorrelationID.Get(), 203 msg.errorCode.Get(), msg.errorMessage.Get()) 204 } 205 case Events.OnCounterReady: 206 logger.Debugf("received ON_COUNTER_READY") 207 208 var msg counterUpdate 209 msg.Wrap(buffer, int(offset)) 210 211 adapter.listener.OnAvailableCounter(msg.correlationID.Get(), msg.counterID.Get()) 212 case Events.OnUnavailableCounter: 213 logger.Debugf("received ON_UNAVAILABLE_COUNTER") 214 215 var msg counterUpdate 216 msg.Wrap(buffer, int(offset)) 217 218 adapter.listener.OnUnavailableCounter(msg.correlationID.Get(), msg.counterID.Get()) 219 case Events.OnClientTimeout: 220 logger.Debugf("received ON_CLIENT_TIMEOUT") 221 222 var msg clientTimeout 223 msg.Wrap(buffer, int(offset)) 224 225 adapter.listener.OnClientTimeout(msg.clientID.Get()) 226 default: 227 // Note: Java silently ignores unhandled events 228 logger.Fatalf("received unhandled %d", msgTypeID) 229 } 230 } 231 232 return adapter.broadcastReceiver.Receive(handler) 233 }