generic_server: Gentle iterator
Add the ability to iterate over the list of connections in a "gentle" manner, i.e. -- preempting the loop when required. Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "to_string.hh"
|
||||
|
||||
#include <seastar/core/when_all.hh>
|
||||
#include <seastar/core/loop.hh>
|
||||
#include <seastar/core/reactor.hh>
|
||||
|
||||
namespace generic_server {
|
||||
@@ -30,10 +31,26 @@ connection::~connection()
|
||||
{
|
||||
--_server._current_connections;
|
||||
server::connections_list_t::iterator iter = _server._connections_list.iterator_to(*this);
|
||||
for (auto&& gi : _server._gentle_iterators) {
|
||||
if (gi.iter == iter) {
|
||||
gi.iter++;
|
||||
}
|
||||
}
|
||||
_server._connections_list.erase(iter);
|
||||
_server.maybe_stop();
|
||||
}
|
||||
|
||||
future<> server::for_each_gently(noncopyable_function<void(const connection&)> fn) {
|
||||
_gentle_iterators.emplace_front(*this);
|
||||
std::list<gentle_iterator>::iterator gi = _gentle_iterators.begin();
|
||||
return seastar::do_until([ gi ] { return gi->iter == gi->end; },
|
||||
[ gi, fn = std::move(fn) ] {
|
||||
fn(*(gi->iter++));
|
||||
return make_ready_future<>();
|
||||
}
|
||||
).finally([ this, gi ] { _gentle_iterators.erase(gi); });
|
||||
}
|
||||
|
||||
static bool is_broken_pipe_or_connection_reset(std::exception_ptr ep) {
|
||||
try {
|
||||
std::rethrow_exception(ep);
|
||||
|
||||
@@ -82,6 +82,13 @@ protected:
|
||||
future<> _stopped = _all_connections_stopped.get_future();
|
||||
using connections_list_t = boost::intrusive::list<connection>;
|
||||
connections_list_t _connections_list;
|
||||
struct gentle_iterator {
|
||||
connections_list_t::const_iterator iter, end;
|
||||
gentle_iterator(const server& s) : iter(s._connections_list.begin()), end(s._connections_list.end()) {}
|
||||
gentle_iterator(const gentle_iterator&) = delete;
|
||||
gentle_iterator(gentle_iterator&&) = delete;
|
||||
};
|
||||
std::list<gentle_iterator> _gentle_iterators;
|
||||
std::vector<server_socket> _listeners;
|
||||
|
||||
public:
|
||||
@@ -102,6 +109,8 @@ protected:
|
||||
|
||||
virtual future<> unadvertise_connection(shared_ptr<connection> conn);
|
||||
|
||||
future<> for_each_gently(noncopyable_function<void(const connection&)>);
|
||||
|
||||
void maybe_stop();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user