Skip to content
Snippets Groups Projects
Commit da4998ea authored by Vladislav Shpilevoy's avatar Vladislav Shpilevoy
Browse files

raft: factor out the code to wakeup worker fiber

Raft has a worker fiber to perform async tasks such as WAL write,
state broadcast.

The worker was created and woken up from 2 places, leading at
least to code duplication. The patch wraps it into a new function
raft_worker_wakeup(), and uses it.

The patch is not need for anything functional, but was created
while working on #5339 and trying ideas. The patch seems to be
good refactoring making the code simpler, and therefore it is
submitted.
parent bd0da669
No related branches found
No related tags found
No related merge requests found
......@@ -178,6 +178,13 @@ raft_election_quorum(void)
return MIN(replication_synchro_quorum, replicaset.registered_count);
}
/**
* Wakeup the Raft worker fiber in order to do some async work. If the fiber
* does not exist yet, it is created.
*/
static void
raft_worker_wakeup(void);
/** Schedule broadcast of the complete Raft state to all the followers. */
static void
raft_schedule_broadcast(void);
......@@ -670,10 +677,8 @@ raft_sm_pause_and_dump(void)
if (raft.is_write_in_progress)
return;
ev_timer_stop(loop(), &raft.timer);
raft_worker_wakeup();
raft.is_write_in_progress = true;
if (raft.worker == NULL)
raft.worker = fiber_new("raft_worker", raft_worker_f);
fiber_wakeup(raft.worker);
}
static void
......@@ -988,21 +993,43 @@ raft_new_term(void)
}
static void
raft_schedule_broadcast(void)
raft_worker_wakeup(void)
{
raft.is_broadcast_scheduled = true;
if (raft.worker == NULL) {
raft.worker = fiber_new("raft_worker", raft_worker_f);
if (raft.worker == NULL) {
/*
* XXX: should be handled properly, no need to panic.
* The issue though is that most of the Raft state
* machine functions are not supposed to fail, and also
* they usually wakeup the fiber when their work is
* finished. So it is too late to fail. On the other
* hand it looks not so good to create the fiber when
* Raft is initialized. Because then it will occupy
* memory even if Raft is not used.
*/
diag_log();
panic("Could't create Raft worker fiber");
return;
}
fiber_set_joinable(raft.worker, true);
}
/*
* Don't wake the fiber if it writes something. Otherwise it would be a
* spurious wakeup breaking the WAL write not adapted to this.
* spurious wakeup breaking the WAL write not adapted to this. Also
* don't wakeup the current fiber - it leads to undefined behaviour.
*/
if (raft.is_write_in_progress)
return;
if (raft.worker == NULL)
raft.worker = fiber_new("raft_worker", raft_worker_f);
if (raft.worker != fiber())
if (!raft.is_write_in_progress && fiber() != raft.worker)
fiber_wakeup(raft.worker);
}
static void
raft_schedule_broadcast(void)
{
raft.is_broadcast_scheduled = true;
raft_worker_wakeup();
}
void
raft_init(void)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment