Always send an empty changeset to the first call of a Results notification callback

This commit is contained in:
Thomas Goyne 2016-03-11 14:43:08 -08:00
parent b5bd00005c
commit 9503a3fc03
3 changed files with 22 additions and 7 deletions

View File

@ -208,8 +208,15 @@ bool BackgroundCollection::deliver(SharedGroup& sg, std::exception_ptr err)
void BackgroundCollection::call_callbacks()
{
while (auto fn = next_callback()) {
fn(m_changes_to_deliver, m_error);
while (auto cb = next_callback()) {
auto fn = cb->fn;
if (!cb->initial_delivered && should_deliver_initial()) {
cb->initial_delivered = true;
fn({}, m_error); // note: may invalidate `cb`
}
else {
fn(m_changes_to_deliver, m_error);
}
}
if (m_error) {
@ -220,7 +227,7 @@ void BackgroundCollection::call_callbacks()
}
}
CollectionChangeCallback BackgroundCollection::next_callback()
BackgroundCollection::Callback* BackgroundCollection::next_callback()
{
std::lock_guard<std::mutex> callback_lock(m_callback_mutex);
@ -230,9 +237,7 @@ CollectionChangeCallback BackgroundCollection::next_callback()
if (!m_error && !deliver_initial && m_changes_to_deliver.empty()) {
continue;
}
callback.initial_delivered = true;
return callback.fn;
return &callback;
}
m_callback_index = npos;

View File

@ -158,7 +158,7 @@ private:
// remove_callback() updates this when needed
size_t m_callback_index = npos;
CollectionChangeCallback next_callback();
Callback* next_callback();
};
} // namespace _impl

View File

@ -283,6 +283,16 @@ TEST_CASE("Results") {
r->notify();
REQUIRE(notification_calls == 1);
}
SECTION("the first call of a notification always passes an empty change even if it previously ran for a different callback") {
auto token2 = results.add_notification_callback([&](CollectionChangeIndices c, std::exception_ptr) {
REQUIRE(c.empty());
});
write([&] {
table->set_int(0, table->add_empty_row(), 5);
});
}
}
// Sort in descending order