| #ifndef PROTON_MESSAGING_HANDLER_HPP |
| #define PROTON_MESSAGING_HANDLER_HPP |
| |
| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| #include "./fwd.hpp" |
| #include "./internal/export.hpp" |
| |
| /// @file |
| /// @copybrief proton::messaging_handler |
| |
| namespace proton { |
| |
| /// A handler for Proton messaging events. |
| /// |
| /// Subclass and override the event-handling member functions. |
| /// |
| /// Event handling functions can always use the objects passed as |
| /// arguments. |
| /// |
| /// @note A handler function **must not** use proton objects that are |
| /// not accessible via the arguments passed without taking extra |
| /// care. For example an on_message() handler called for connection |
| /// "A" cannot simply call sender::send() on a proton::sender |
| /// belonging to connection "B". |
| /// |
| /// **Thread-safety**: To be safe for both single- and multi-threaded |
| /// use, a handler **must not** directly use objects belonging to |
| /// another connection. See @ref mt_page and proton::work_queue for |
| /// safe ways to communicate. We recommend writing safe handlers to |
| /// avoid mysterious failures if the handler is ever used in a |
| /// multi-threaded container. |
| /// |
| /// **Single-threaded only**: An application is single-threaded if it |
| /// calls container::run() exactly once, and does not make proton |
| /// calls from any other thread. In this case a handler can use |
| /// objects belonging to another connection, but it must call |
| /// connection::wake() on the other connection before returning. Such |
| /// a handler will fail mysteriously if the container is run with |
| /// multiple threads. |
| /// |
| /// #### Close and error handling |
| /// |
| /// There are several objects that have `on_X_close` and `on_X_error` |
| /// functions. They are called as follows: |
| /// |
| /// - If `X` is closed cleanly, with no error status, then `on_X_close` |
| /// is called. |
| /// |
| /// - If `X` is closed with an error, then `on_X_error` is called, |
| /// followed by `on_X_close`. The error condition is also available |
| /// in `on_X_close` from `X::error()`. |
| /// |
| /// By default, if you do not implement `on_X_error`, it will call |
| /// `on_error`. If you do not implement `on_error` it will throw a |
| /// `proton::error` exception, which may not be what you want but |
| /// does help to identify forgotten error handling quickly. |
| /// |
| /// #### Resource cleanup |
| /// |
| /// Every `on_X_open` event is paired with an `on_X_close` event which |
| /// can clean up any resources created by the open handler. In |
| /// particular this is still true if an error is reported with an |
| /// `on_X_error` event. The error-handling logic doesn't have to |
| /// manage resource clean up. It can assume that the close event will |
| /// be along to handle it. |
| class |
| PN_CPP_CLASS_EXTERN messaging_handler { |
| public: |
| PN_CPP_EXTERN messaging_handler(); |
| PN_CPP_EXTERN virtual ~messaging_handler(); |
| |
| /// The container event loop is starting. |
| /// |
| /// This is the first event received after calling |
| /// `container::run()`. |
| PN_CPP_EXTERN virtual void on_container_start(container&); |
| |
| /// The container event loop is stopping. |
| /// |
| /// This is the last event received before the container event |
| /// loop stops. |
| PN_CPP_EXTERN virtual void on_container_stop(container&); |
| |
| /// A message is received. |
| PN_CPP_EXTERN virtual void on_message(delivery&, message&); |
| |
| /// A message can be sent. |
| PN_CPP_EXTERN virtual void on_sendable(sender&); |
| |
| /// The underlying network transport is open |
| PN_CPP_EXTERN virtual void on_transport_open(transport&); |
| |
| /// The underlying network transport has closed. |
| PN_CPP_EXTERN virtual void on_transport_close(transport&); |
| |
| /// The underlying network transport has closed with an error |
| /// condition. |
| PN_CPP_EXTERN virtual void on_transport_error(transport&); |
| |
| /// The remote peer opened the connection. |
| PN_CPP_EXTERN virtual void on_connection_open(connection&); |
| |
| /// The remote peer closed the connection. |
| PN_CPP_EXTERN virtual void on_connection_close(connection&); |
| |
| /// The remote peer closed the connection with an error condition. |
| PN_CPP_EXTERN virtual void on_connection_error(connection&); |
| |
| /// The remote peer opened the session. |
| PN_CPP_EXTERN virtual void on_session_open(session&); |
| |
| /// The remote peer closed the session. |
| PN_CPP_EXTERN virtual void on_session_close(session&); |
| |
| /// The remote peer closed the session with an error condition. |
| PN_CPP_EXTERN virtual void on_session_error(session&); |
| |
| /// The remote peer opened the link. |
| PN_CPP_EXTERN virtual void on_receiver_open(receiver&); |
| |
| /// The remote peer detached the link. |
| PN_CPP_EXTERN virtual void on_receiver_detach(receiver&); |
| |
| /// The remote peer closed the link. |
| PN_CPP_EXTERN virtual void on_receiver_close(receiver&); |
| |
| /// The remote peer closed the link with an error condition. |
| PN_CPP_EXTERN virtual void on_receiver_error(receiver&); |
| |
| /// The remote peer opened the link. |
| PN_CPP_EXTERN virtual void on_sender_open(sender&); |
| |
| /// The remote peer detached the link. |
| PN_CPP_EXTERN virtual void on_sender_detach(sender&); |
| |
| /// The remote peer closed the link. |
| PN_CPP_EXTERN virtual void on_sender_close(sender&); |
| |
| /// The remote peer closed the link with an error condition. |
| PN_CPP_EXTERN virtual void on_sender_error(sender&); |
| |
| /// The receiving peer accepted a transfer. |
| PN_CPP_EXTERN virtual void on_tracker_accept(tracker&); |
| |
| /// The receiving peer rejected a transfer. |
| PN_CPP_EXTERN virtual void on_tracker_reject(tracker&); |
| |
| /// The receiving peer released a transfer. |
| PN_CPP_EXTERN virtual void on_tracker_release(tracker&); |
| |
| /// The receiving peer settled a transfer. |
| PN_CPP_EXTERN virtual void on_tracker_settle(tracker&); |
| |
| /// The sending peer settled a transfer. |
| PN_CPP_EXTERN virtual void on_delivery_settle(delivery&); |
| |
| /// **Unsettled API** - The receiving peer has requested a drain of |
| /// remaining credit. |
| PN_CPP_EXTERN virtual void on_sender_drain_start(sender&); |
| |
| /// **Unsettled API** - The credit outstanding at the time of the |
| /// drain request has been consumed or returned. |
| PN_CPP_EXTERN virtual void on_receiver_drain_finish(receiver&); |
| |
| /// **Unsettled API** - An event that can be triggered from |
| /// another thread. |
| /// |
| /// This event is triggered by a call to `connection::wake()`. It |
| /// is used to notify the application that something needs |
| /// attention. |
| /// |
| /// **Thread-safety** - The application handler and the triggering |
| /// thread must use some form of thread-safe state or |
| /// communication to tell the handler what it needs to do. See |
| /// `proton::work_queue` for an easier way to execute code safely |
| /// in the handler thread. |
| /// |
| /// @note Spurious calls to `on_connection_wake()` can occur |
| /// without any application call to `connection::wake()`. |
| PN_CPP_EXTERN virtual void on_connection_wake(connection&); |
| |
| /// Fallback error handling. |
| PN_CPP_EXTERN virtual void on_error(const error_condition&); |
| }; |
| |
| } // proton |
| |
| #endif // PROTON_MESSAGING_HANDLER_HPP |