// HandleMessagingEvent handles an event, called in the handler goroutine. func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) { switch t { case proton.MStart: h.injecter = e.Injecter() case proton.MLinkOpening: if e.Link().IsReceiver() { h.startReceiver(e) } else { h.startSender(e) } case proton.MLinkClosed: h.linkClosed(e.Link(), e.Link().RemoteCondition().Error()) case proton.MSendable: if s, ok := h.senders[e.Link()]; ok { s.sendable() // Signal the send goroutine that we have credit. } else { proton.CloseError(e.Link(), amqp.Errorf(amqp.NotFound, "link %s sender not found", e.Link())) } case proton.MMessage: m, err := e.Delivery().Message() // Message() must be called while handling the MMessage event. if err != nil { proton.CloseError(e.Link(), err) break } r, ok := h.receivers[e.Link()] if !ok { proton.CloseError(e.Link(), amqp.Errorf(amqp.NotFound, "link %s receiver not found", e.Link())) break } // This will not block as AMQP credit is set to the buffer capacity. r.buffer <- receivedMessage{e.Delivery(), m} util.Debugf("link %s received %s", e.Link(), util.FormatMessage(m)) case proton.MConnectionClosed, proton.MDisconnected: for l, _ := range h.receivers { h.linkClosed(l, nil) } for l, _ := range h.senders { h.linkClosed(l, nil) } } }
func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) { switch t { case proton.MMessage: if r, ok := h.links[e.Link()].(*receiver); ok { r.message(e.Delivery()) } else { h.linkError(e.Link(), "no receiver") } case proton.MSettled: if sm, ok := h.sentMessages[e.Delivery()]; ok { d := e.Delivery().Remote() sm.ack <- Outcome{sentStatus(d.Type()), d.Condition().Error(), sm.value} delete(h.sentMessages, e.Delivery()) } case proton.MSendable: if s, ok := h.links[e.Link()].(*sender); ok { s.sendable() } else { h.linkError(e.Link(), "no sender") } case proton.MConnectionOpening: h.connection.heartbeat = e.Transport().RemoteIdleTimeout() if e.Connection().State().LocalUninit() { // Remotely opened h.incoming(newIncomingConnection(h.connection)) } h.connection.wakeSync() case proton.MSessionOpening: if e.Session().State().LocalUninit() { // Remotely opened h.incoming(newIncomingSession(h, e.Session())) } h.sessions[e.Session()].wakeSync() case proton.MSessionClosed: h.sessionClosed(e.Session(), proton.EndpointError(e.Session())) case proton.MLinkOpening: l := e.Link() if ss := h.sessions[l.Session()]; ss != nil { if l.State().LocalUninit() { // Remotely opened. if l.IsReceiver() { h.incoming(newIncomingReceiver(ss, l)) } else { h.incoming(newIncomingSender(ss, l)) } } if ep, ok := h.links[l]; ok { ep.wakeSync() } else { h.linkError(l, "no link") } } else { h.linkError(l, "no session") } case proton.MLinkClosing: e.Link().Close() case proton.MLinkClosed: h.linkClosed(e.Link(), proton.EndpointError(e.Link())) case proton.MConnectionClosing: h.connection.err.Set(e.Connection().RemoteCondition().Error()) case proton.MConnectionClosed: h.shutdown(proton.EndpointError(e.Connection())) case proton.MDisconnected: err := e.Transport().Condition().Error() if err == nil { err = amqp.Errorf(amqp.IllegalState, "unexpected disconnect on %s", h.connection) } h.shutdown(err) } }
func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) { switch t { case proton.MMessage: if r, ok := h.links[e.Link()].(*receiver); ok { r.message(e.Delivery()) } else { h.internalError(e.Link(), "no receiver for link") } case proton.MSettled: if sm := h.sentMessages[e.Delivery()]; sm != nil { sm.settled(nil) } case proton.MSendable: if s, ok := h.links[e.Link()].(*sender); ok { s.sendable() } else { h.internalError(e.Link(), "no sender for link") } case proton.MSessionOpening: if e.Session().State().LocalUninit() { // Remotely opened incoming := &IncomingSession{h: h, pSession: e.Session()} h.connection.accept(incoming) if err := incoming.error("rejected session %s", e.Session()); err != nil { proton.CloseError(e.Session(), err) } } case proton.MSessionClosed: err := proton.EndpointError(e.Session()) for l, _ := range h.links { if l.Session() == e.Session() { h.linkClosed(l, err) } } delete(h.sessions, e.Session()) case proton.MLinkOpening: l := e.Link() if l.State().LocalActive() { // Already opened locally. break } ss := h.sessions[l.Session()] if ss == nil { h.internalError(e.Link(), "no session for link") break } var incoming Incoming if l.IsReceiver() { incoming = &IncomingReceiver{makeIncomingLink(ss, l)} } else { incoming = &IncomingSender{makeIncomingLink(ss, l)} } h.connection.accept(incoming) if err := incoming.error("rejected link %s", e.Link()); err != nil { proton.CloseError(l, err) break } case proton.MLinkClosing: e.Link().Close() case proton.MLinkClosed: h.linkClosed(e.Link(), proton.EndpointError(e.Link())) case proton.MConnectionClosing: h.connection.err.Set(e.Connection().RemoteCondition().Error()) case proton.MConnectionClosed: h.connection.err.Set(Closed) // If no error already set, this is an orderly close. case proton.MDisconnected: h.connection.err.Set(e.Transport().Condition().Error()) // If err not set at this point (e.g. to Closed) then this is unexpected. h.connection.err.Set(amqp.Errorf(amqp.IllegalState, "unexpected disconnect on %s", h.connection)) err := h.connection.Error() for l, _ := range h.links { h.linkClosed(l, err) } for _, s := range h.sessions { s.closed(err) } for _, sm := range h.sentMessages { sm.settled(err) } } }
func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) { switch t { case proton.MMessage: if r, ok := h.links[e.Link()].(*receiver); ok { r.message(e.Delivery()) } else { h.linkError(e.Link(), "no receiver") } case proton.MSettled: if sm, ok := h.sentMessages[e.Delivery()]; ok { d := e.Delivery().Remote() sm.ack <- Outcome{sentStatus(d.Type()), d.Condition().Error(), sm.value} delete(h.sentMessages, e.Delivery()) } case proton.MSendable: if s, ok := h.links[e.Link()].(*sender); ok { s.sendable() } else { h.linkError(e.Link(), "no sender") } case proton.MSessionOpening: if e.Session().State().LocalUninit() { // Remotely opened h.incoming(newIncomingSession(h, e.Session())) } case proton.MSessionClosed: h.sessionClosed(e.Session(), proton.EndpointError(e.Session())) case proton.MLinkOpening: l := e.Link() if l.State().LocalActive() { // Already opened locally. break } ss := h.sessions[l.Session()] if ss == nil { h.linkError(e.Link(), "no session") break } if l.IsReceiver() { h.incoming(&IncomingReceiver{makeIncomingLink(ss, l)}) } else { h.incoming(&IncomingSender{makeIncomingLink(ss, l)}) } case proton.MLinkClosing: e.Link().Close() case proton.MLinkClosed: h.linkClosed(e.Link(), proton.EndpointError(e.Link())) case proton.MConnectionClosing: h.connection.err.Set(e.Connection().RemoteCondition().Error()) case proton.MConnectionClosed: h.connectionClosed(proton.EndpointError(e.Connection())) case proton.MDisconnected: h.connection.err.Set(e.Transport().Condition().Error()) // If err not set at this point (e.g. to Closed) then this is unexpected. h.connection.err.Set(amqp.Errorf(amqp.IllegalState, "unexpected disconnect on %s", h.connection)) err := h.connection.Error() for l, _ := range h.links { h.linkClosed(l, err) } h.links = nil for _, s := range h.sessions { s.closed(err) } h.sessions = nil for _, sm := range h.sentMessages { sm.ack <- Outcome{Unacknowledged, err, sm.value} } h.sentMessages = nil } }
func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) { switch t { case proton.MMessage: if r, ok := h.links[e.Link()].(*receiver); ok { r.handleDelivery(e.Delivery()) } else { h.connection.closed( amqp.Errorf(amqp.InternalError, "cannot find receiver for link %s", e.Link())) } case proton.MSettled: if sm := h.sentMessages[e.Delivery()]; sm != nil { sm.settled(nil) } case proton.MSessionOpening: if e.Session().State().LocalUninit() { // Remotely opened s := newSession(h.connection, e.Session()) h.sessions[e.Session()] = s if h.connection.incoming != nil { h.connection.incoming.In <- s } else { proton.CloseError(e.Session(), amqp.Errorf(amqp.NotAllowed, "remote sessions not allowed")) } } case proton.MSessionClosing: e.Session().Close() case proton.MSessionClosed: err := e.Session().RemoteCondition().Error() for l, _ := range h.links { if l.Session() == e.Session() { h.linkClosed(l, err) } } delete(h.sessions, e.Session()) case proton.MLinkOpening: l := e.Link() if l.State().LocalUninit() { // Remotely opened if h.connection.incoming == nil { proton.CloseError(l, amqp.Errorf(amqp.NotAllowed, ("no remote links"))) break } s := h.sessions[l.Session()] if s == nil { proton.CloseError( l, amqp.Errorf(amqp.InternalError, ("cannot find session for link"))) break } h.connection.handleIncoming(s, l) } case proton.MLinkClosing: e.Link().Close() case proton.MLinkClosed: h.linkClosed(e.Link(), e.Link().RemoteCondition().Error()) case proton.MDisconnected: err := h.connection.Error() for l, _ := range h.links { h.linkClosed(l, err) } for _, s := range h.sessions { s.closed(err) } for _, sm := range h.sentMessages { sm.settled(err) } } }