@@ -130,6 +130,22 @@ class ServerState { // public struct - to allow initialization.
130
130
gstate_ = s;
131
131
}
132
132
133
+ bool AllowInlineScheduling () const {
134
+ // We can't allow inline scheduling during a full sync, because then journaling transactions
135
+ // will be scheduled before RdbLoader::LoadItemsBuffer is finished. We can't use the regular
136
+ // locking mechanism because RdbLoader is not using transactions.
137
+
138
+ // Journal callbacks can preempt; This means we have to disallow inline scheduling
139
+ // because then we might interleave the callbacks loop from an inlined-scheduled command
140
+ // and a normally-scheduled command.
141
+ // The problematic loop is in JournalSlice::AddLogRecord, going over all the callbacks.
142
+ return !journal_callbacks_active_ && gstate_ != GlobalState::LOADING;
143
+ }
144
+
145
+ void SetJournalCallbacksActive (bool is_allowed) {
146
+ journal_callbacks_active_ = is_allowed;
147
+ }
148
+
133
149
// Borrow interpreter from internal manager. Return int with ReturnInterpreter.
134
150
Interpreter* BorrowInterpreter ();
135
151
@@ -206,6 +222,11 @@ class ServerState { // public struct - to allow initialization.
206
222
mi_heap_t * data_heap_;
207
223
journal::Journal* journal_ = nullptr ;
208
224
225
+ // Inline scheduling is an optimization for running in low thread count situations.
226
+ // Since it bypasses the regular transactions mechanism, it has to be disabled in
227
+ // some situations.
228
+ bool journal_callbacks_active_ = false ;
229
+
209
230
InterpreterManager interpreter_mgr_;
210
231
absl::flat_hash_map<ScriptMgr::ScriptKey, ScriptMgr::ScriptParams> cached_script_params_;
211
232
0 commit comments