blob: 6eb3755d941bbadc9990448115e04e63f33d5f74 [file] [log] [blame]
#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