Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr/14 #15

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revert "Commit to pr/14"
This reverts commit 9ef26fa.
  • Loading branch information
Dominic Lapointe committed Oct 4, 2020
commit f8576a3e8688d263dfa494e812c898eb59c829b8
100 changes: 100 additions & 0 deletions include/eosio/watcher_plugin/http_async_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#pragma once

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/use_future.hpp>
#include <fc/variant.hpp>
#include <fc/reflect/variant.hpp>
#include <fc/time.hpp>
#include <fc/network/http/http_client.hpp>
#include <thread>

namespace eosio {

using namespace fc;
namespace asio = boost::asio;

template <typename F>
struct final_action {
final_action(F f) : clean{f} {}
~final_action() { clean(); }
private:
F clean;
};

template <typename F>
final_action<F> finally(F f) {
return final_action<F>(f);
}

class http_async_client {
public:

http_async_client() : sync_client(std::make_unique<http_client>()),
work_guard(asio::make_work_guard(ioc)) {
}

~http_async_client() {
work_guard.reset();
}

void start() {
worker = std::make_unique<std::thread>( [this]() {
ioc.run();
});
}

void stop() {
work_guard.reset();
worker->join();
}

// TODO: return result as future
template<typename T>
void post(const url& dest, const T& payload,
const time_point& deadline = time_point::maximum()) {

// Make sure only sync_client and these arguments (copied by value) are accessed from
// separate tread.
// T type could have pointers, but it doesn't make sense for payload to have them anyway.
asio::post( ioc.get_executor(), [this, dest, payload, deadline]() {
post_sync(dest, payload, deadline);
});
}

// TODO: implement. Add call_impl function which could be used by post as well as these.
// void add_cert(const std::string& cert_pem_string);
// void set_verify_peers(bool enabled);

private:
template <typename T>
void post_sync(const url& dest, const T& payload,
const time_point& deadline = time_point::maximum()) {

auto exit = finally( [this](){ retry = true; } );

try {
sync_client->post_sync(dest, payload, deadline);
} catch( const fc::eof_exception& exc) {
// FIXME: http_client expects body in response and throws eof if it doesn't get it.
} catch( const fc::assert_exception& exc ) {
// Thrown when sending or reading response fails
// Try once more
wlog("Exception while trying to send: ${exc}", ("exc", exc.to_detail_string()));
if( retry ) {
wlog("Trying again");
retry = false;
post_sync(dest, payload, deadline);
}
}
FC_CAPTURE_AND_LOG( (dest)(payload)(deadline) )

}

std::unique_ptr<http_client> sync_client;
std::unique_ptr<std::thread> worker;
asio::io_context ioc;
asio::executor_work_guard<asio::io_context::executor_type> work_guard;
bool retry = true;

};
}
32 changes: 32 additions & 0 deletions include/eosio/watcher_plugin/watcher_plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @file
* @copyright eosauthority - free to use and modify - see LICENSE.txt
*/
#pragma once
#include <appbase/application.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>

namespace eosio {

using namespace appbase;

typedef std::unique_ptr<class watcher_plugin_impl> watcher_plugin_ptr;

class watcher_plugin : public appbase::plugin<watcher_plugin> {
public:
watcher_plugin();
virtual ~watcher_plugin();

APPBASE_PLUGIN_REQUIRES((chain_plugin))

virtual void set_program_options(options_description&, options_description& cfg) override;

void plugin_initialize(const variables_map& options);
void plugin_startup();
void plugin_shutdown();

private:
watcher_plugin_ptr my;
};

}