mirror of
https://github.com/matrix-construct/construct
synced 2024-06-08 04:58:58 +02:00
ircd::server: Optimize peers map w/ allocator::node.
This commit is contained in:
parent
500413701b
commit
0036111ef1
|
@ -11,11 +11,6 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_SERVER_PEER_H
|
||||
|
||||
namespace ircd::server
|
||||
{
|
||||
extern std::map<string_view, std::unique_ptr<peer>> peers;
|
||||
}
|
||||
|
||||
/// Remote entity.
|
||||
///
|
||||
struct ircd::server::peer
|
||||
|
@ -40,6 +35,7 @@ struct ircd::server::peer
|
|||
static uint64_t ids;
|
||||
|
||||
uint64_t id {++ids};
|
||||
peers_node_type node;
|
||||
std::string hostcanon; // hostname:service[:port]
|
||||
net::ipport remote;
|
||||
system_point remote_expires;
|
||||
|
@ -56,6 +52,7 @@ struct ircd::server::peer
|
|||
template<class F> size_t accumulate_links(F&&) const;
|
||||
template<class F> size_t accumulate_tags(F&&) const;
|
||||
|
||||
void del();
|
||||
void handle_finished();
|
||||
void open_links();
|
||||
void handle_resolve_A(const hostport &, const json::array &);
|
||||
|
|
|
@ -26,7 +26,14 @@ namespace ircd::server
|
|||
IRCD_EXCEPTION(error, unavailable);
|
||||
IRCD_EXCEPTION(error, canceled);
|
||||
|
||||
using peers_value_type = std::pair<const string_view, peer *>;
|
||||
using peers_allocator_state = allocator::node<peers_value_type>;
|
||||
using peers_allocator = typename peers_allocator_state::allocator;
|
||||
using peers_map_type = std::map<string_view, peer *, std::less<>, peers_allocator>;
|
||||
using peers_node_type = std::pair<typename peers_map_type::node_type, peers_value_type>;
|
||||
|
||||
extern conf::item<bool> enable;
|
||||
extern peers_map_type peers;
|
||||
}
|
||||
|
||||
#include "tag.h"
|
||||
|
|
106
ircd/server.cc
106
ircd/server.cc
|
@ -14,8 +14,10 @@ namespace ircd::server
|
|||
extern log::log log;
|
||||
extern ctx::dock dock;
|
||||
extern conf::item<seconds> close_all_timeout;
|
||||
extern peers_allocator_state peers_alloc;
|
||||
|
||||
// Internal util
|
||||
template<class F> static bool for_each_peer_safe(F&&);
|
||||
template<class F> static size_t accumulate_peers(F&&);
|
||||
template<class F> static size_t accumulate_links(F&&);
|
||||
template<class F> static size_t accumulate_tags(F&&);
|
||||
|
@ -24,6 +26,8 @@ namespace ircd::server
|
|||
// Internal control
|
||||
static decltype(ircd::server::peers)::iterator
|
||||
create(const net::hostport &, decltype(peers)::iterator &);
|
||||
|
||||
static void clear();
|
||||
}
|
||||
#pragma GCC visibility pop
|
||||
|
||||
|
@ -51,6 +55,15 @@ ircd::server::close_all_timeout
|
|||
{ "default", 2L },
|
||||
};
|
||||
|
||||
decltype(ircd::server::peers_alloc)
|
||||
ircd::server::peers_alloc;
|
||||
|
||||
decltype(ircd::server::peers)
|
||||
ircd::server::peers
|
||||
{
|
||||
peers_alloc
|
||||
};
|
||||
|
||||
//
|
||||
// init
|
||||
//
|
||||
|
@ -64,8 +77,22 @@ noexcept
|
|||
ircd::server::init::~init()
|
||||
noexcept
|
||||
{
|
||||
interrupt(), close(), wait();
|
||||
peers.clear();
|
||||
interrupt();
|
||||
close();
|
||||
wait();
|
||||
clear();
|
||||
}
|
||||
|
||||
void
|
||||
ircd::server::clear()
|
||||
{
|
||||
for_each_peer_safe([](const auto &peer)
|
||||
{
|
||||
peer->del();
|
||||
return true;
|
||||
});
|
||||
|
||||
assert(peers.empty());
|
||||
log::debug
|
||||
{
|
||||
log, "All server peers, connections, and requests are clear."
|
||||
|
@ -116,8 +143,12 @@ ircd::server::close()
|
|||
|
||||
net::close_opts opts;
|
||||
opts.timeout = seconds(close_all_timeout);
|
||||
for(auto &peer : peers)
|
||||
peer.second->close(opts);
|
||||
for_each_peer_safe([&opts]
|
||||
(const auto &peer)
|
||||
{
|
||||
peer->close(opts);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -217,7 +248,12 @@ ircd::server::create(const net::hostport &hostport,
|
|||
assert(bool(peer));
|
||||
assert(!empty(peer->hostcanon));
|
||||
const string_view key{peer->hostcanon};
|
||||
it = peers.emplace_hint(it, key, std::move(peer));
|
||||
const typename peers_allocator_state::scope alloca
|
||||
{
|
||||
server::peers, peer->node
|
||||
};
|
||||
|
||||
it = peers.emplace_hint(it, key, peer.release());
|
||||
assert(it->second->hostcanon.data() == it->first.data());
|
||||
return it;
|
||||
}
|
||||
|
@ -453,6 +489,24 @@ ircd::server::accumulate_peers(F&& closure)
|
|||
});
|
||||
}
|
||||
|
||||
template<class F>
|
||||
bool
|
||||
ircd::server::for_each_peer_safe(F&& closure)
|
||||
{
|
||||
std::vector<peer *> peers(server::peers.size());
|
||||
std::transform(begin(server::peers), end(server::peers), begin(peers), []
|
||||
(const auto &pair)
|
||||
{
|
||||
return pair.second;
|
||||
});
|
||||
|
||||
for(const auto &peer : peers)
|
||||
if(!closure(peer))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::server::canonize(const net::hostport &hostport)
|
||||
{
|
||||
|
@ -696,14 +750,6 @@ catch(const std::exception &e)
|
|||
// server/peer.h
|
||||
//
|
||||
|
||||
decltype(ircd::server::peers)
|
||||
ircd::server::peers
|
||||
{};
|
||||
|
||||
//
|
||||
// server::peer
|
||||
//
|
||||
|
||||
decltype(ircd::server::peer::MAX_LINK)
|
||||
ircd::server::peer::MAX_LINK
|
||||
{
|
||||
|
@ -1881,6 +1927,40 @@ ircd::server::peer::handle_finished()
|
|||
{
|
||||
assert(finished());
|
||||
|
||||
log::debug
|
||||
{
|
||||
log, "peer(%p) id:%lu finished; tags:%zu wrote:%zu read:%zu err:%d :%s",
|
||||
this,
|
||||
id,
|
||||
tag_done,
|
||||
write_bytes,
|
||||
read_bytes,
|
||||
err_has(),
|
||||
hostcanon,
|
||||
};
|
||||
|
||||
//TODO: XXX
|
||||
if(ircd::run::level == ircd::run::level::RUN)
|
||||
if(err_has())
|
||||
return;
|
||||
|
||||
del();
|
||||
}
|
||||
|
||||
void
|
||||
ircd::server::peer::del()
|
||||
{
|
||||
// unlink from map
|
||||
assert(finished());
|
||||
const auto erased
|
||||
{
|
||||
peers.erase(this->hostcanon)
|
||||
};
|
||||
|
||||
// self-destruct
|
||||
assert(erased);
|
||||
delete this;
|
||||
|
||||
// Right now this is what the server:: ~init sequence needs
|
||||
// to wait for all links to close on IRCd shutdown.
|
||||
server::dock.notify_all();
|
||||
|
|
Loading…
Reference in a new issue