Instantiating a heartbeat class

#include <stasher/heartbeat.H>

class application_id;

class application_status;

typedef stasher::heartbeat<application_id, application_status> heartbeat;

class heartbeatThreadObj : virtual public stasher::obj {

    heartbeat::obj_type *heartbeat_ptr;

    application_status status;

public:

    heartbeatThreadObj(const application_status &initial_status)
        : status(initial_status)
    {
    }

    void run(const heartbeat &heartbeat_arg)
    {
        heartbeatptr= &*heartbeat_arg;

// ...
    }

    void dispatch(const status_msg &msg)
    {
        status=msg.status;
    }

    void dispatch(const post_update_msg &msg)
    {
        heartbeatptr->update(msg.update_msg, status);
    }
};

auto client=stasher::client::base::connect();

auto manager=stasher::manager::create();

auto thread=x::ref<heartbeatThreadObj>::create("initial_status");

x::run(thread, heartbeat::create(client, manager,
                                 "status",
                                 application_id("manager_node"),
                                 L"update_interval", std::chrono::minutes(10),
                                 L"stale_interval", std::chrono::minutes(5),
                                 [thread]
                                 (heartbeat::base::update_type_t update_type)
                                 {
                                     thread->post_update(update_type);
                                 }));

stasher::heartbeat takes two template parameters, the name of the class that serves as the application instance identifier (each instance of the application must use a unique one), and a class that serves as each instance's status. All instances of the application must declare the same application_id and application_status. application_id and application_status must support everything that any instance needs to use to identify itself, or to announce its status. The reference-counted stasher::heartbeat's create() function takes the following arguments:

The constructor installs a managed object subscription for the heartbeat object. The subscription remains active until the hearbeat object goes out of scope and gets destroyed, at which time the subscription is terminated.

Note

The client connection handle and the manager object must remain in scope as long as the heartbeat object exists. They cannot be destroyed until the heartbeat object gets destroyed.

If a manager object gets destroyed, the heartbeat object may stop getting updated from the object repository.

The heartbeat object holds a reference on the client connection handle, and the application must destroy the heartbeat object before all of its own references to the client connection handle go out of scope. If they do, the heartbeat object ends up having the last reference to the client connection handle in scope. This will likely result in a deadlock, for the same reasons that are described in the section called “What asynchronous C++ API methods can and cannot do”.