LCOV - code coverage report
Current view: top level - eventdispatcher - connection_with_send_message.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 123 4.9 %
Date: 2022-06-18 10:10:36 Functions: 4 22 18.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2012-2022  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/eventdispatcher
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License along
      17             : // with this program; if not, write to the Free Software Foundation, Inc.,
      18             : // 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             : 
      20             : /** \file
      21             :  * \brief Implementation of the Connection with Send Message class.
      22             :  *
      23             :  * This is a base class which ease the implementation of a connection
      24             :  * which is able to send and receive messages.
      25             :  */
      26             : 
      27             : 
      28             : // self
      29             : //
      30             : #include    "eventdispatcher/connection_with_send_message.h"
      31             : 
      32             : #include    "eventdispatcher/connection.h"
      33             : #include    "eventdispatcher/dispatcher_support.h"
      34             : #include    "eventdispatcher/exception.h"
      35             : 
      36             : 
      37             : // snaplogger
      38             : //
      39             : #include    <snaplogger/logger.h>
      40             : #include    <snaplogger/message.h>
      41             : 
      42             : 
      43             : // snapdev
      44             : //
      45             : #include    <snapdev/not_used.h>
      46             : 
      47             : 
      48             : // boost
      49             : //
      50             : #include    <boost/algorithm/string/join.hpp>
      51             : 
      52             : 
      53             : // C
      54             : //
      55             : #ifdef __SANITIZE_ADDRESS__
      56             : #include    <sanitizer/lsan_interface.h>
      57             : #endif
      58             : 
      59             : 
      60             : // last include
      61             : //
      62             : #include    <snapdev/poison.h>
      63             : 
      64             : 
      65             : 
      66             : namespace ed
      67             : {
      68             : 
      69             : 
      70             : 
      71             : /** \brief Initialize the connection.
      72             :  *
      73             :  * This constructor initialize the connection with a send_message() function.
      74             :  * The function takes an optional \p service_name which is used in various
      75             :  * messages such as the REGISTER and UNREGISTER messages.
      76             :  *
      77             :  * If the \p service_name parameter is an empty string, then the functions
      78             :  * that require that name throw when reached.
      79             :  *
      80             :  * \param[in] service_name  The name of your service.
      81             :  *
      82             :  * \sa register_service()
      83             :  * \sa unregister_service()
      84             :  */
      85           3 : connection_with_send_message::connection_with_send_message(std::string const & service_name)
      86           3 :     : f_service_name(service_name)
      87             : {
      88           3 : }
      89             : 
      90             : 
      91             : /** \brief Clean up.
      92             :  *
      93             :  * The destructor makes sure to clean up the connection with send_message()
      94             :  * objects.
      95             :  */
      96           3 : connection_with_send_message::~connection_with_send_message()
      97             : {
      98           3 : }
      99             : 
     100             : 
     101             : 
     102             : /** \brief Reply to the watchdog message ALIVE.
     103             :  *
     104             :  * To check whether a service is alive, send the ALIVE message. This
     105             :  * function builds an ABSOLUTELY reply and attaches the "serial" parameter
     106             :  * as is if present in the ALIVE message. It also includes the original
     107             :  * "timestamp" parameter.
     108             :  *
     109             :  * The function also adds one field named "reply_timestamp" with the Unix
     110             :  * time in seconds when the reply is being sent.
     111             :  *
     112             :  * \note
     113             :  * The "serial" parameter is expected to be used to make sure that no messages
     114             :  * are lost, or if loss is expected, to see whether loss is heavy or not.
     115             :  *
     116             :  * \note
     117             :  * The "serial" and "timestamp" parameters do not get checked. If present
     118             :  * in the original message, they get copied verbatim to the destination.
     119             :  * This allows you to include anything you want in those parameters although
     120             :  * we suggest you use the "timestamp" only for a value representing time.
     121             :  *
     122             :  * \param[in] msg  The ALIVE message.
     123             :  */
     124           0 : void connection_with_send_message::msg_alive(message & msg)
     125             : {
     126           0 :     message absolutely;
     127           0 :     absolutely.user_data(msg.user_data<void>());
     128           0 :     absolutely.reply_to(msg);
     129           0 :     absolutely.set_command("ABSOLUTELY");
     130           0 :     if(msg.has_parameter("serial"))
     131             :     {
     132           0 :         absolutely.add_parameter("serial", msg.get_parameter("serial"));
     133             :     }
     134           0 :     if(msg.has_parameter("timestamp"))
     135             :     {
     136           0 :         absolutely.add_parameter("timestamp", msg.get_parameter("timestamp"));
     137             :     }
     138           0 :     absolutely.add_parameter("reply_timestamp", time(nullptr));
     139           0 :     if(!send_message(absolutely, false))
     140             :     {
     141           0 :         SNAP_LOG_WARNING
     142             :             << "could not reply to \""
     143           0 :             << msg.get_command()
     144             :             << "\" with an ABSOLUTELY message."
     145             :             << SNAP_LOG_SEND;
     146             :     }
     147           0 : }
     148             : 
     149             : 
     150             : /** \brief Build the HELP reply and send it.
     151             :  *
     152             :  * When a daemon registers with the snapcommunicator, it sends a REGISTER
     153             :  * command. As a result, your daemon is sent a HELP command which must be
     154             :  * answered with a COMMANDS message which includes the list of commands
     155             :  * (a.k.a. messages) that your daemon supports.
     156             :  *
     157             :  * The list of commands is built using the list of Expression() strings
     158             :  * found in the dispatcher of your daemon. If that list includes null
     159             :  * pointers or custom match functions, then the list is deemed to
     160             :  * include functions that the default loop cannot determine. As a result,
     161             :  * your help() function will be called and it must be overridden, otherwise
     162             :  * it will call the default which throws.
     163             :  *
     164             :  * \exception implementation_error
     165             :  * This exception is thrown if the resulting list of commands is empty.
     166             :  *
     167             :  * \param[in] msg  The HELP message.
     168             :  *
     169             :  * \sa help()
     170             :  */
     171           0 : void connection_with_send_message::msg_help(message & msg)
     172             : {
     173           0 :     snapdev::NOT_USED(msg);
     174             : 
     175           0 :     bool need_user_help(true);
     176           0 :     string_list_t commands;
     177             : 
     178             :     dispatcher_base * d;
     179           0 :     dispatcher_support * ds(dynamic_cast<dispatcher_support *>(this));
     180           0 :     if(ds != nullptr)
     181             :     {
     182             :         // we extract the bare pointer because in the other case
     183             :         // we only get a bare pointer... (which we can't safely
     184             :         // put in a shared pointer, although we could attempt to
     185             :         // use shared_from_this() but we could have a class without
     186             :         // it?)
     187             :         //
     188           0 :         d = ds->get_dispatcher().get();
     189             :     }
     190             :     else
     191             :     {
     192           0 :         d = dynamic_cast<dispatcher_base *>(this);
     193             :     }
     194           0 :     if(d != nullptr)
     195             :     {
     196           0 :         need_user_help = d->get_commands(commands);
     197             :     }
     198             : 
     199             :     // the user has "unknown" commands (as far as the dispatcher is concerned)
     200             :     // in his list of commands so we have to let him enter them "manually"
     201             :     //
     202             :     // this happens whenever there is an entry which is a regular expression
     203             :     // or something similar which we just cannot grab
     204             :     //
     205           0 :     if(need_user_help)
     206             :     {
     207           0 :         help(commands);
     208             :     }
     209             : 
     210             :     // the list of commands just cannot be empty
     211             :     //
     212           0 :     if(commands.empty())
     213             :     {
     214             :         throw implementation_error(
     215             :                 "connection_with_send_message::msg_help()"
     216           0 :                 " is not able to determine the commands this messenger supports");
     217             :     }
     218             : 
     219             :     // Now prepare the COMMAND message and send it
     220             :     //
     221             :     // Note: we turn off the caching on this message, it does not make sense
     222             :     //       because if snapcommunicator is not running, then caching won't
     223             :     //       happen work anyway (i.e. snapcommunicator has to send HELP first
     224             :     //       and then we send the reply, if it has to restart, then just
     225             :     //       sending COMMANDS will fail.)
     226             :     //
     227           0 :     message reply;
     228           0 :     reply.user_data(msg.user_data<void>());
     229           0 :     reply.set_command("COMMANDS");
     230           0 :     reply.add_parameter("list", boost::algorithm::join(commands, ","));
     231           0 :     if(!send_message(reply, false))
     232             :     {
     233           0 :         SNAP_LOG_WARNING
     234             :             << "could not reply to \""
     235           0 :             << msg.get_command()
     236             :             << "\" with a COMMANDS message."
     237             :             << SNAP_LOG_SEND;
     238             :     }
     239           0 : }
     240             : 
     241             : 
     242             : /** \brief Run the sanitizer leak checker.
     243             :  *
     244             :  * This function calls the function printing out all the leaks found
     245             :  * at this time in this software (\em leaks as in any block of memory
     246             :  * currently allocated).
     247             :  *
     248             :  * The message does nothing if the library was not compiled with the
     249             :  * sanitizer feature turned on.
     250             :  *
     251             :  * The message can be sent any number of times.
     252             :  *
     253             :  * \note
     254             :  * This is a debug message only.
     255             :  *
     256             :  * \todo
     257             :  * Find a solution which actually works. The LSAN system doesn't offer
     258             :  * to (correctly) print the list of leaks at any given time.
     259             :  *
     260             :  * \param[in] msg  The LEAK message, which is ignored.
     261             :  */
     262           0 : void connection_with_send_message::msg_leak(ed::message & msg)
     263             : {
     264           0 :     snapdev::NOT_USED(msg);
     265             : 
     266             : #ifdef __SANITIZE_ADDRESS__
     267           0 :     __lsan_do_recoverable_leak_check();
     268             : #else
     269             :     std::cerr << "error: leaks are not being tracked;"
     270             :                 " use the --sanitize option to turn on this feature."
     271             :         << std::endl;
     272             : #endif
     273           0 : }
     274             : 
     275             : 
     276             : /** \brief Reopen file-based logger appenders.
     277             :  *
     278             :  * Whenever logrotate runs or some changes are made to the log
     279             :  * definitions, the corresponding daemons need to reopen snaplogger
     280             :  * to make use of the new file and settings. This command is used
     281             :  * for that purpose.
     282             :  *
     283             :  * \note
     284             :  * If the snaplogger is not currently configured, this message is
     285             :  * ignored.
     286             :  *
     287             :  * \param[in] msg  The LOG_ROTATE message.
     288             :  */
     289           0 : void connection_with_send_message::msg_log_rotate(message & msg)
     290             : {
     291           0 :     snapdev::NOT_USED(msg);
     292             : 
     293           0 :     if(snaplogger::is_configured())
     294             :     {
     295             :         // send log in the old file and format
     296             :         //
     297           0 :         SNAP_LOG_INFO
     298             :             << "-------------------- Logging reconfiguration request."
     299             :             << SNAP_LOG_SEND;
     300             : 
     301             :         // reconfigure
     302             :         //
     303           0 :         snaplogger::reopen();
     304             : 
     305             :         // send log to new file and format
     306             :         //
     307           0 :         SNAP_LOG_INFO
     308             :             << "-------------------- Logging reconfiguration done."
     309             :             << SNAP_LOG_SEND;
     310             :     }
     311           0 : }
     312             : 
     313             : 
     314             : /** \brief Call you stop() function with true.
     315             :  *
     316             :  * This command means that someone is asking your daemon to quit as soon as
     317             :  * possible because the Snap! environment is being asked to shutdown.
     318             :  *
     319             :  * The value 'true' means that all the daemons are being asked to stop and
     320             :  * not just you.
     321             :  *
     322             :  * \param[in] msg  The QUITTING message.
     323             :  *
     324             :  * \sa msg_stop()
     325             :  * \sa stop()
     326             :  */
     327           0 : void connection_with_send_message::msg_quitting(message & msg)
     328             : {
     329           0 :     snapdev::NOT_USED(msg);
     330             : 
     331           0 :     stop(true);
     332           0 : }
     333             : 
     334             : 
     335             : /** \brief Calls your ready() function with the message.
     336             :  *
     337             :  * All daemons using the snapcommunicator daemon have to have a ready()
     338             :  * function which gets called once the HELP and COMMAND message were
     339             :  * handled. This is when your daemon is expected to be ready to start
     340             :  * working. Some daemons start working immediately no matter
     341             :  * what (i.e. snapwatchdog and snapfirewall do work either way), but
     342             :  * those are rare.
     343             :  *
     344             :  * \param[in] msg  The READY message.
     345             :  *
     346             :  * \sa ready()
     347             :  */
     348           0 : void connection_with_send_message::msg_ready(message & msg)
     349             : {
     350             :     // pass the message so any additional info can be accessed.
     351             :     //
     352           0 :     ready(msg);
     353           0 : }
     354             : 
     355             : 
     356             : /** \brief Calls your restart() function with the message.
     357             :  *
     358             :  * This message has no implementation by default. What we want to
     359             :  * do is find a clean way to restart any service instantly.
     360             :  *
     361             :  * The RESTART message is expected to be used whenever a modification
     362             :  * to some file or the system environment somehow affects your service
     363             :  * in such a way that it requires a restart. For example, after an
     364             :  * upgrade of the eventdispatcher library, you should restart all the
     365             :  * services that make use of it. For this reason, we have a RESTART
     366             :  * message.
     367             :  *
     368             :  * The message comes with one parameter named `reason` which describes
     369             :  * why the RESTART was sent:
     370             :  *
     371             :  * \li `reason=upgrade` -- something (library/tools) was upgraded
     372             :  * \li `reason=config` -- a configuration file was updated
     373             :  *
     374             :  * \note
     375             :  * At the time we created this message, a live configuration was not
     376             :  * available. Now that we have the fluid-settings service, that changed
     377             :  * and in most cases, `reason=config` should not be necessary anymore.
     378             :  * (only for fluid-settings itself and for some parameters not found
     379             :  * in the fluid-settings).
     380             :  *
     381             :  * \note
     382             :  * There are currently some services that make use of a CONFIG message
     383             :  * whenever their configuration changes. Pretty much all services do
     384             :  * not support a live configuration change (because it initializes their
     385             :  * objects from the configuration data once on startup and in many cases
     386             :  * it would be very complicated to allow for changes to occur on the fly).
     387             :  * \note
     388             :  * In those existing implementations, we really just do a restart anyway.
     389             :  * \note
     390             :  * The new versions will be using fluid-settings. We can still support
     391             :  * a RESTART message, but a RELOADCONFIG (as we had in snapcommunicator)
     392             :  * should not be used.
     393             :  *
     394             :  * \param[in] msg  The RESTART message.
     395             :  *
     396             :  * \sa restart()
     397             :  */
     398           0 : void connection_with_send_message::msg_restart(message & msg)
     399             : {
     400             :     // pass the message so any additional info can be accessed.
     401             :     //
     402           0 :     restart(msg);
     403           0 : }
     404             : 
     405             : 
     406             : /** \brief Call you stop() function with false.
     407             :  *
     408             :  * This command means that someone is asking your daemon to stop.
     409             :  *
     410             :  * The value 'false' means just your daemon was asked to stop and not the
     411             :  * entire system to shutdown (otherwise you would receive a QUITTING command
     412             :  * instead.)
     413             :  *
     414             :  * \param[in] msg  The STOP message.
     415             :  *
     416             :  * \sa msg_quitting()
     417             :  */
     418           0 : void connection_with_send_message::msg_stop(message & msg)
     419             : {
     420           0 :     snapdev::NOT_USED(msg);
     421             : 
     422           0 :     stop(false);
     423           0 : }
     424             : 
     425             : 
     426             : /** \brief Handle the UNKNOWN message.
     427             :  *
     428             :  * Whenever we send a command to another daemon, that command can be refused
     429             :  * by sending an UNKNOWN reply. This function handles the UNKNOWN command
     430             :  * by simply recording that as an error in the logs.
     431             :  *
     432             :  * \param[in] msg  The UNKNOWN message we just received.
     433             :  */
     434           0 : void connection_with_send_message::msg_log_unknown(message & msg)
     435             : {
     436             :     // we sent a command that the other end did not understand
     437             :     // and got an UNKNOWN reply
     438             :     //
     439           0 :     SNAP_LOG_ERROR
     440             :         << "we sent command \""
     441           0 :         << msg.get_parameter("command")
     442             :         << "\" and the destination replied with \"UNKNOWN\""
     443             :            " so we probably did not get the expected result."
     444             :         << SNAP_LOG_SEND;
     445           0 : }
     446             : 
     447             : 
     448             : /** \brief Send the UNKNOWN message as a reply.
     449             :  *
     450             :  * This function replies to the \p message with the UNKNOWN message as
     451             :  * expected by all our connection objects when a service receives a
     452             :  * message it does not know how to handle.
     453             :  *
     454             :  * It is expected to be used in your dispatcher_match array.
     455             :  *
     456             :  * \note
     457             :  * This function is virtual which allows you to add it to your array of
     458             :  * of dispatcher_match items. The following shows an example of what that
     459             :  * can look like.
     460             :  *
     461             :  * \code
     462             :  *  {
     463             :  *      ed::dispatcher<my_connection>::define_match(
     464             :  *          ...
     465             :  *      ),
     466             :  *      ...
     467             :  *
     468             :  *      // ALWAYS LAST
     469             :  *      ed::dispatcher<my_connection>::define_catch_all()
     470             :  *  };
     471             :  * \endcode
     472             :  *
     473             :  * \param[in] msg  The message to reply to.
     474             :  */
     475           0 : void connection_with_send_message::msg_reply_with_unknown(message & msg)
     476             : {
     477           0 :     message unknown;
     478           0 :     unknown.user_data(msg.user_data<void>());
     479           0 :     unknown.reply_to(msg);
     480           0 :     unknown.set_command("UNKNOWN");
     481           0 :     unknown.add_parameter("command", msg.get_command());
     482           0 :     if(!send_message(unknown, false))
     483             :     {
     484           0 :         SNAP_LOG_WARNING
     485             :             << "could not reply to \""
     486           0 :             << msg.get_command()
     487             :             << "\" with UNKNOWN message."
     488             :             << SNAP_LOG_SEND;
     489             :     }
     490             :     else
     491             :     {
     492           0 :         SNAP_LOG_MINOR
     493             :             << "unknown command \""
     494           0 :             << msg.get_command()
     495             :             << "\"."
     496             :             << SNAP_LOG_SEND;
     497             :     }
     498           0 : }
     499             : 
     500             : 
     501             : /** \brief The default help() function does nothing.
     502             :  *
     503             :  * This implementation does nothing. It is expected that you reimplement
     504             :  * this function depending on your daemon's need.
     505             :  *
     506             :  * The help() function gets called whenever the list of commands can't be
     507             :  * 100% defined automatically.
     508             :  *
     509             :  * Your function is expected to add commands to the \p commands parameter
     510             :  * as in:
     511             :  *
     512             :  * \code
     513             :  *      commands.push_back("MSG1");
     514             :  *      commands.push_back("MSG2");
     515             :  *      commands.push_back("MSG3");
     516             :  * \endcode
     517             :  *
     518             :  * This allows you to handle those three messages with a single entry in
     519             :  * your list of dispatcher_match objects with a regular expression such
     520             :  * as "MSG[1-3]".
     521             :  *
     522             :  * \param[in,out] commands  List of commands to update.
     523             :  */
     524           0 : void connection_with_send_message::help(string_list_t & commands)
     525             : {
     526           0 :     snapdev::NOT_USED(commands);
     527             : 
     528             :     // do nothing by default -- user is expected to overload this function
     529           0 : }
     530             : 
     531             : 
     532             : /** \brief The default ready() function does nothing.
     533             :  *
     534             :  * This implementation does nothing. It is expected that you reimplement
     535             :  * this function depending on your daemon's need. Most often this function
     536             :  * is the one that really starts your daemons process.
     537             :  *
     538             :  * \param[in,out] msg  The READY message.
     539             :  */
     540           0 : void connection_with_send_message::ready(message & msg)
     541             : {
     542           0 :     snapdev::NOT_USED(msg);
     543             : 
     544             :     // do nothing by default -- user is expected to overload this function
     545             :     //
     546           0 :     SNAP_LOG_WARNING
     547             :         << "default ready() function was called."
     548             :         << SNAP_LOG_SEND;
     549           0 : }
     550             : 
     551             : 
     552             : /** \brief The default restart() function does nothing.
     553             :  *
     554             :  * This implementation does nothing. It is expected that you reimplement
     555             :  * this function depending on your daemon's need. Most often this function
     556             :  * calls the stop() function in order to restart the daemon. If only a
     557             :  * configuration file changed and your daemon is capable of reading the
     558             :  * new settings without a full restart, then just read that new config.
     559             :  *
     560             :  * \param[in,out] msg  The RESTART message.
     561             :  *
     562             :  * \sa msg_restart()
     563             :  */
     564           0 : void connection_with_send_message::restart(message & msg)
     565             : {
     566           0 :     snapdev::NOT_USED(msg);
     567             : 
     568             :     // do nothing by default -- user is expected to overload this function
     569             :     //
     570           0 :     SNAP_LOG_WARNING
     571             :         << "default restart() function was called."
     572             :         << SNAP_LOG_SEND;
     573           0 : }
     574             : 
     575             : 
     576             : /** \brief The default stop() function does nothing.
     577             :  *
     578             :  * This implementation does nothing. It is expected that you reimplement
     579             :  * this function depending on your daemon's need.
     580             :  *
     581             :  * \param[in] quitting  Whether the QUITTING (true) or STOP (false) command
     582             :  *                      was received.
     583             :  */
     584           0 : void connection_with_send_message::stop(bool quitting)
     585             : {
     586           0 :     snapdev::NOT_USED(quitting);
     587             : 
     588             :     // do nothing by default -- user is expected to overload this function
     589             :     //
     590           0 :     SNAP_LOG_WARNING
     591             :         << "default stop() function was called."
     592             :         << SNAP_LOG_SEND;
     593           0 : }
     594             : 
     595             : 
     596             : /** \brief Retrieve the name of this service.
     597             :  *
     598             :  * A messenger used with the snapcommunicator is viewed as a service and
     599             :  * it needs to have a name. That name is specified at the time you create
     600             :  * your service (see constructor).
     601             :  *
     602             :  * This function returns that name.
     603             :  *
     604             :  * \exception name_undefined
     605             :  * When \p required is true, this function make raise a `name_undefined` if
     606             :  * the service name is empty. Fix this issue by adding the name in your
     607             :  * constructor.
     608             :  *
     609             :  * \param[in] required  Set to true if you want to raise an error when the
     610             :  * service name is not defined.
     611             :  *
     612             :  * \return The service name of this connection.
     613             :  */
     614           0 : std::string connection_with_send_message::get_service_name(bool required) const
     615             : {
     616           0 :     if(required
     617           0 :     && f_service_name.empty())
     618             :     {
     619           0 :         throw name_undefined("service name is required but not available.");
     620             :     }
     621             : 
     622           0 :     return f_service_name;
     623             : }
     624             : 
     625             : 
     626             : /** \brief Register your snapcommunicator service.
     627             :  *
     628             :  * This function registers your snapcommunicator service by sending
     629             :  * the REGISTER command to it. The service name must have been defined
     630             :  * in your constructor.
     631             :  *
     632             :  * The function is expected to be called in your process_connected()
     633             :  * function.
     634             :  *
     635             :  * \code
     636             :  *     void my_messenger::process_connected()
     637             :  *     {
     638             :  *         // make sure to call default function
     639             :  *         snap_tcp_client_permanent_message_connection::process_connected();
     640             :  *
     641             :  *         // then register
     642             :  *         register_service();
     643             :  *     }
     644             :  * \endcode
     645             :  *
     646             :  * \note
     647             :  * The function generates a fatal error if the send_message() fails.
     648             :  * However, you are responsible for quitting your service if the function
     649             :  * returns false. This very function does not attempt anything more.
     650             :  *
     651             :  * \exception name_undefined
     652             :  * The function makes use of the service name as specified in the
     653             :  * constructor. It cannot be empty.
     654             :  *
     655             :  * \return true if the send_message() succeeded.
     656             :  */
     657           0 : bool connection_with_send_message::register_service()
     658             : {
     659           0 :     message register_msg;
     660           0 :     register_msg.set_command("REGISTER");
     661           0 :     register_msg.add_parameter("service", get_service_name());
     662           0 :     register_msg.add_version_parameter();
     663           0 :     if(!send_message(register_msg, false))
     664             :     {
     665           0 :         SNAP_LOG_FATAL
     666             :             << "could not REGISTER with snapcommunicator."
     667             :             << SNAP_LOG_SEND;
     668           0 :         return false;
     669             :     }
     670             : 
     671           0 :     return true;
     672             : }
     673             : 
     674             : 
     675             : /** \brief Unregister from the snapcommunicator.
     676             :  *
     677             :  * The register_service() function registers your service with the
     678             :  * snapcommunicator. This function is the converse. It sends a message
     679             :  * to UNREGISTER you from the snapcommunicator. This means other services
     680             :  * will not be able to send you messages anymore.
     681             :  *
     682             :  * \exception name_undefined
     683             :  * The function makes use of the service name as specified in the
     684             :  * constructor. It cannot be empty.
     685             :  */
     686           0 : void connection_with_send_message::unregister_service()
     687             : {
     688             :     // mark ourself as done so once the last message(s) were sent,
     689             :     // we get automatically removed from the communicator
     690             :     //
     691           0 :     connection * c(dynamic_cast<connection *>(this));
     692           0 :     if(c == nullptr)
     693             :     {
     694           0 :         throw implementation_error("ed::connection_with_send_message must derive from ed::connection.");
     695             :     }
     696           0 :     c->mark_done();
     697             : 
     698             :     // unregister ourself from the snapcommunicator daemon
     699             :     //
     700           0 :     message unregister_msg;
     701           0 :     unregister_msg.set_command("UNREGISTER");
     702           0 :     unregister_msg.add_parameter("service", get_service_name(true));
     703           0 :     if(!send_message(unregister_msg, false))
     704             :     {
     705           0 :         SNAP_LOG_WARNING
     706             :             << "could not UNREGISTER from snapcommunicator."
     707             :             << SNAP_LOG_SEND;
     708             :     }
     709           0 : }
     710             : 
     711             : 
     712             : 
     713           6 : } // namespace ed
     714             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13