[tarantool-patches] [PATCH 1/1] swim: keep encoded round message cached
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Wed Apr 10 13:55:15 MSK 2019
During a SWIM round a message is being handed out consisting of
at most 4 sections. Parts of the message change rarely along with
a member attribute update, or with removal of a member. So it is
possible to cache the message and send it during several round
steps in a row. Or even do not rebuild it the whole round.
Part of #3234
---
Branch: https://github.com/tarantool/tarantool/tree/gerold103/gh-3234-swim-cached-msg
Issue: https://github.com/tarantool/tarantool/issues/3234
src/lib/swim/swim.c | 24 ++++++++++++++++++++----
src/lib/swim/swim_io.h | 7 +++++++
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/lib/swim/swim.c b/src/lib/swim/swim.c
index c64b8df3a..8453295a5 100644
--- a/src/lib/swim/swim.c
+++ b/src/lib/swim/swim.c
@@ -417,6 +417,13 @@ struct swim {
struct rlist dissemination_queue;
};
+/** Reset cached round message on any change of any member. */
+static inline void
+cached_round_msg_invalidate(struct swim *swim)
+{
+ swim_packet_create(&swim->round_step_task.packet);
+}
+
/** Put the member into a list of ACK waiters. */
static void
swim_wait_ack(struct swim *swim, struct swim_member *member)
@@ -456,6 +463,7 @@ static void
swim_on_member_update(struct swim *swim, struct swim_member *member)
{
member->unacknowledged_pings = 0;
+ cached_round_msg_invalidate(swim);
swim_register_event(swim, member);
}
@@ -588,6 +596,7 @@ swim_delete_member(struct swim *swim, struct swim_member *member)
mh_int_t rc = mh_swim_table_find(swim->members, key, NULL);
assert(rc != mh_end(swim->members));
mh_swim_table_del(swim->members, rc, NULL);
+ cached_round_msg_invalidate(swim);
rlist_del_entry(member, in_round_queue);
/* Failure detection component. */
@@ -836,8 +845,11 @@ swim_encode_dissemination(struct swim *swim, struct swim_packet *packet)
/** Encode SWIM components into a UDP packet. */
static void
-swim_encode_round_msg(struct swim *swim, struct swim_packet *packet)
+swim_encode_round_msg(struct swim *swim)
{
+ if (swim_packet_body_size(&swim->round_step_task.packet) > 0)
+ return;
+ struct swim_packet *packet = &swim->round_step_task.packet;
swim_packet_create(packet);
char *header = swim_packet_alloc(packet, 1);
int map_size = 0;
@@ -872,6 +884,7 @@ swim_decrease_event_ttl(struct swim *swim)
tmp) {
if (--member->status_ttl == 0) {
rlist_del_entry(member, in_dissemination_queue);
+ cached_round_msg_invalidate(swim);
if (member->status == MEMBER_LEFT)
swim_delete_member(swim, member);
}
@@ -901,8 +914,7 @@ swim_begin_step(struct ev_loop *loop, struct ev_timer *t, int events)
*/
if (rlist_empty(&swim->round_queue))
return;
-
- swim_encode_round_msg(swim, &swim->round_step_task.packet);
+ swim_encode_round_msg(swim);
struct swim_member *m =
rlist_first_entry(&swim->round_queue, struct swim_member,
in_round_queue);
@@ -1559,7 +1571,6 @@ swim_delete(struct swim *swim)
swim_scheduler_destroy(&swim->scheduler);
swim_ev_timer_stop(loop(), &swim->round_tick);
swim_ev_timer_stop(loop(), &swim->wait_ack_tick);
- swim_task_destroy(&swim->round_step_task);
mh_int_t node;
mh_foreach(swim->members, node) {
struct swim_member *m =
@@ -1570,6 +1581,11 @@ swim_delete(struct swim *swim)
rlist_del_entry(m, in_dissemination_queue);
swim_member_delete(m);
}
+ /*
+ * Destroy the task after members - otherwise they would
+ * try to invalidate the already destroyed task.
+ */
+ swim_task_destroy(&swim->round_step_task);
wait_ack_heap_destroy(&swim->wait_ack_heap);
mh_swim_table_delete(swim->members);
free(swim->shuffled);
diff --git a/src/lib/swim/swim_io.h b/src/lib/swim/swim_io.h
index a6032127d..30016f904 100644
--- a/src/lib/swim/swim_io.h
+++ b/src/lib/swim/swim_io.h
@@ -126,6 +126,13 @@ swim_packet_alloc(struct swim_packet *packet, int size)
return res;
}
+/** Size of the packet body. Meta is not counted. */
+static inline int
+swim_packet_body_size(const struct swim_packet *packet)
+{
+ return packet->pos - packet->body;
+}
+
/** Initialize @a packet, reserve some space for meta. */
void
swim_packet_create(struct swim_packet *packet);
--
2.17.2 (Apple Git-113)
More information about the Tarantool-patches
mailing list