• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / 1856

22 Nov 2023 04:32PM UTC coverage: 91.666% (-0.02%) from 91.689%
1856

push

Evergreen

web-flow
Fix duplication of recoverable list changes after unrecoverable changes (#7155)

After we copy a list in client reset recovery we need to not apply any changes
to that list in subsequent transactions as we copy directly to the final state
of the list and applying changes would just duplicate those changes.

This is only applicable to flexible sync when there's a subscription change in
between the write with unrecoverable changes and the write with recoverable
changes.

92274 of 169124 branches covered (0.0%)

77 of 77 new or added lines in 3 files covered. (100.0%)

120 existing lines in 16 files now uncovered.

231289 of 252317 relevant lines covered (91.67%)

6368856.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.32
/src/realm/sync/noinst/client_reset_operation.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2021 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#include <realm/sync/noinst/client_reset_operation.hpp>
20

21
#include <realm/sync/history.hpp>
22
#include <realm/sync/noinst/client_history_impl.hpp>
23
#include <realm/sync/noinst/client_reset.hpp>
24
#include <realm/transaction.hpp>
25
#include <realm/util/scope_exit.hpp>
26

27
namespace realm::_impl::client_reset {
28

29
namespace {
30

31
constexpr static std::string_view c_fresh_suffix(".fresh");
32

33
} // namespace
34

35
std::string get_fresh_path_for(const std::string& path)
36
{
3,693,628✔
37
    const size_t suffix_len = c_fresh_suffix.size();
3,693,628✔
38
    REALM_ASSERT(path.length());
3,693,628✔
39
    REALM_ASSERT_DEBUG_EX(
3,693,628✔
40
        path.size() < suffix_len || path.substr(path.size() - suffix_len, suffix_len) != c_fresh_suffix, path);
3,693,628✔
41
    return path + c_fresh_suffix.data();
3,693,628✔
42
}
3,693,628✔
43

44
bool is_fresh_path(const std::string& path)
45
{
3,398✔
46
    const size_t suffix_len = c_fresh_suffix.size();
3,398✔
47
    REALM_ASSERT(path.length());
3,398✔
48
    if (path.size() < suffix_len) {
3,398✔
49
        return false;
×
50
    }
×
51
    return path.substr(path.size() - suffix_len, suffix_len) == c_fresh_suffix;
3,398✔
52
}
3,398✔
53

54
bool perform_client_reset(util::Logger& logger, DB& db, DB& fresh_db, ClientResyncMode mode,
55
                          CallbackBeforeType notify_before, CallbackAfterType notify_after,
56
                          sync::SaltedFileIdent new_file_ident, sync::SubscriptionStore* sub_store,
57
                          util::FunctionRef<void(int64_t)> on_flx_version, bool recovery_is_allowed)
58
{
408✔
59
    REALM_ASSERT(mode != ClientResyncMode::Manual);
408✔
60
    logger.debug("Possibly beginning client reset operation: realm_path = %1, mode = %2, recovery_allowed = %3",
408✔
61
                 db.get_path(), mode, recovery_is_allowed);
408✔
62

204✔
63
    auto always_try_clean_up = util::make_scope_exit([&]() noexcept {
408✔
64
        std::string path_to_clean = fresh_db.get_path();
408✔
65
        try {
408✔
66
            fresh_db.close();
408✔
67
            constexpr bool delete_lockfile = true;
408✔
68
            DB::delete_files(path_to_clean, nullptr, delete_lockfile);
408✔
69
        }
408✔
70
        catch (const std::exception& err) {
204✔
UNCOV
71
            logger.warn("In ClientResetOperation::finalize, the fresh copy '%1' could not be cleaned up due to "
×
UNCOV
72
                        "an exception: '%2'",
×
UNCOV
73
                        path_to_clean, err.what());
×
74
            // ignored, this is just a best effort
UNCOV
75
        }
×
76
    });
408✔
77

204✔
78
    // only do the reset if there is data to reset
204✔
79
    // if there is nothing in this Realm, then there is nothing to reset and
204✔
80
    // sync should be able to continue as normal
204✔
81
    auto latest_version = db.get_version_id_of_latest_snapshot();
408✔
82
    bool local_realm_exists = latest_version.version > 1;
408✔
83
    if (!local_realm_exists) {
408✔
84
        logger.debug("Local Realm file has never been written to, so skipping client reset.");
4✔
85
        return false;
4✔
86
    }
4✔
87

202✔
88
    VersionID frozen_before_state_version = notify_before ? notify_before() : latest_version;
404✔
89

202✔
90
    // If m_notify_after is set, pin the previous state to keep it around.
202✔
91
    TransactionRef previous_state;
404✔
92
    if (notify_after) {
404✔
93
        previous_state = db.start_frozen(frozen_before_state_version);
248✔
94
    }
248✔
95
    bool did_recover_out = false;
404✔
96
    client_reset::perform_client_reset_diff(db, fresh_db, new_file_ident, logger, mode, recovery_is_allowed,
404✔
97
                                            &did_recover_out, sub_store,
404✔
98
                                            on_flx_version); // throws
404✔
99

202✔
100
    if (notify_after) {
404✔
101
        notify_after(previous_state->get_version_of_current_transaction(), did_recover_out);
188✔
102
    }
188✔
103

202✔
104
    return true;
404✔
105
}
404✔
106

107
} // namespace realm::_impl::client_reset
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc