stasher::manager->manage_serverstatusupdates(): maintaining server status updates

#include <iostream>
#include <stasher/client.H>
#include <stasher/manager.H>
#include <stasher/managedserverstatuscallback.H>
#include <x/fmtsize.H>

#include <string>

class mycallbackObj : public stasher::managedserverstatuscallbackObj {

public:
	mycallbackObj() {}
	~mycallbackObj() noexcept {}

	void connection_update(stasher::req_stat_t status) override
	{
		std::cout << ("Connection update: " + x::tostring(status)
			      + "\n") << std::flush;
	}

	void serverinfo(const stasher::userhelo &serverinfo) override
	{
		std::cout << "Connected to " << serverinfo.nodename
			  << " (cluster " << serverinfo.clustername << ")"
			  << std::endl;

		std::cout << "Maximum "
			  << serverinfo.limits.maxobjects
			  << " objects, "
			  << x::fmtsize(serverinfo.limits.maxobjectsize)
			  << " aggregate object size, per transaction."
			  << std::endl
			  << "Maximum "
			  << serverinfo.limits.maxsubs
			  << " concurrent subscriptions." << std::endl;
	}

	void state(const stasher::clusterstate &state) override
	{
		std::cout << "Current master: " << state.master
			  << std::endl;

		for (auto &node:state.nodes)
		{
			std::cout << "    Peer: " << node << std::endl;
		}

		std::cout << "Quorum: full="
			  << x::tostring(state.full)
			  << ", majority="
			  << x::tostring(state.majority) << std::endl;
	}
};


void managedserverstatussubscriber()
{
	stasher::client client=stasher::client::base::connect();

	auto manager=stasher::manager::create(L"", "10 seconds");

	std::cout << "Subscribing to server status, press ENTER to stop"
		  << std::endl;

	auto subscriber=x::ref<mycallbackObj>::create();

	x::ref<x::obj> mcguffin=manager->
		manage_serverstatusupdates(client, subscriber);

	std::string dummy;
	std::getline(std::cin, dummy);
}

int main()
{
	try {
		managedserverstatussubscriber();
	} catch (const x::exception &e)
	{
		std::cerr << e << std::endl;
		exit(1);
	}

	return 0;
}

This is a managed version of subscribeserverstatus(). The example above is nearly identical to examples/subscribeserverstatus.C except for the subclassing of stasher::managedserverstatuscallbackObj and implementint the additional connect_update() callback with the same semantics as it has with the other manage_name() methods:

$ ./serverstatusupdates
Subscribing to server status, press ENTER to stop
Connected to octopus.objrepo.example.com (cluster objrepo.example.com)
Maximum 10 objects, 32 Mb aggregate object size, per transaction.
Maximum 10 concurrent subscriptions.
Connection update: Transaction/request processed
Current master: monster.objrepo.example.com
    Peer: monster.objrepo.example.com
Quorum: full=true, majority=true
Connection update: Connection to the server failed
Connected to octopus.objrepo.example.com (cluster objrepo.example.com)
Maximum 10 objects, 32 Mb aggregate object size, per transaction.
Maximum 10 concurrent subscriptions.
Connection update: Transaction/request processed
Current master: monster.objrepo.example.com
    Peer: monster.objrepo.example.com
Quorum: full=true, majority=true

As always, the manager object takes care of reconnecting. All the callbacks in this example have certain limitations, see the section called “What asynchronous C++ API methods can and cannot do” for more information.