6
6
7
7
#include < atomic>
8
8
9
+ #include " base/logging.h"
9
10
#include " server/db_slice.h"
10
11
#include " server/journal/streamer.h"
11
12
@@ -17,46 +18,58 @@ class OutgoingMigration::SliceSlotMigration {
17
18
SliceSlotMigration (DbSlice* slice, SlotSet slots, uint32_t sync_id, journal::Journal* journal,
18
19
Context* cntx, io::Sink* dest)
19
20
: streamer_(slice, std::move(slots), sync_id, journal, cntx) {
20
- streamer_.Start (dest);
21
21
state_.store (MigrationState::C_FULL_SYNC, memory_order_relaxed);
22
+ sync_fb_ = Fiber (" slot-snapshot" , [this , dest] { streamer_.Start (dest); });
22
23
}
23
24
24
25
void Cancel () {
25
26
streamer_.Cancel ();
26
27
}
27
28
29
+ void WaitForSnapshotFinished () {
30
+ sync_fb_.JoinIfNeeded ();
31
+ }
32
+
28
33
void Finalize () {
29
34
streamer_.SendFinalize ();
30
35
state_.store (MigrationState::C_FINISHED, memory_order_relaxed);
31
36
}
32
37
33
38
MigrationState GetState () const {
34
- auto state = state_.load (memory_order_relaxed);
35
- return state == MigrationState::C_FULL_SYNC && streamer_.IsSnapshotFinished ()
36
- ? MigrationState::C_STABLE_SYNC
37
- : state;
39
+ return state_.load (memory_order_relaxed);
38
40
}
39
41
40
42
private:
41
43
RestoreStreamer streamer_;
42
44
// Atomic only for simple read operation, writes - from the same thread, reads - from any thread
43
45
atomic<MigrationState> state_ = MigrationState::C_CONNECTING;
46
+ Fiber sync_fb_;
44
47
};
45
48
46
49
OutgoingMigration::OutgoingMigration (std::uint32_t flows_num, std::string ip, uint16_t port,
47
50
SlotRanges slots, Context::ErrHandler err_handler)
48
51
: host_ip_(ip), port_(port), slots_(slots), cntx_(err_handler), slot_migrations_(flows_num) {
49
52
}
50
53
51
- OutgoingMigration::~OutgoingMigration () = default ;
54
+ OutgoingMigration::~OutgoingMigration () {
55
+ main_sync_fb_.JoinIfNeeded ();
56
+ }
52
57
53
58
void OutgoingMigration::StartFlow (DbSlice* slice, uint32_t sync_id, journal::Journal* journal,
54
59
io::Sink* dest) {
55
60
const auto shard_id = slice->shard_id ();
56
61
57
- std::lock_guard lck (flows_mu_);
58
- slot_migrations_[shard_id] =
59
- std::make_unique<SliceSlotMigration>(slice, slots_, sync_id, journal, &cntx_, dest);
62
+ MigrationState state = MigrationState::C_NO_STATE;
63
+ {
64
+ std::lock_guard lck (flows_mu_);
65
+ slot_migrations_[shard_id] =
66
+ std::make_unique<SliceSlotMigration>(slice, slots_, sync_id, journal, &cntx_, dest);
67
+ state = GetStateImpl ();
68
+ }
69
+
70
+ if (state == MigrationState::C_FULL_SYNC) {
71
+ main_sync_fb_ = Fiber (" outgoing_migration" , &OutgoingMigration::SyncFb, this );
72
+ }
60
73
}
61
74
62
75
void OutgoingMigration::Finalize (uint32_t shard_id) {
@@ -75,10 +88,20 @@ MigrationState OutgoingMigration::GetState() const {
75
88
MigrationState OutgoingMigration::GetStateImpl () const {
76
89
MigrationState min_state = MigrationState::C_MAX_INVALID;
77
90
for (const auto & slot_migration : slot_migrations_) {
78
- if (slot_migration)
91
+ if (slot_migration) {
79
92
min_state = std::min (min_state, slot_migration->GetState ());
93
+ } else {
94
+ min_state = MigrationState::C_NO_STATE;
95
+ }
80
96
}
81
97
return min_state;
82
98
}
83
99
100
+ void OutgoingMigration::SyncFb () {
101
+ for (auto & migration : slot_migrations_) {
102
+ migration->WaitForSnapshotFinished ();
103
+ }
104
+ VLOG (1 ) << " Migrations snapshot is finihed" ;
105
+ }
106
+
84
107
} // namespace dfly
0 commit comments