void close(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     switch (session.m_config.stop_policy) {
         case SyncSessionStopPolicy::Immediately:
             session.advance_state(lock, inactive);
             break;
         case SyncSessionStopPolicy::LiveIndefinitely:
             // Don't do anything; session lives forever.
             break;
         case SyncSessionStopPolicy::AfterChangesUploaded:
             // Wait for all pending changes to upload.
             session.advance_state(lock, dying);
             break;
     }
 }
 bool revive_if_needed(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Revive.
     session.create_sync_session();
     session.advance_state(lock, waiting_for_access_token);
     return true;
 }
 void refresh_access_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                           std::string access_token,
                           const util::Optional<std::string>& server_url) const override
 {
     // Since the sync session was previously unbound, it's safe to do this from the
     // calling thread.
     if (!session.m_server_url) {
         session.m_server_url = server_url;
     }
     if (session.m_session_has_been_bound) {
         session.m_session->refresh(std::move(access_token));
     } else {
         session.m_session->bind(*session.m_server_url, std::move(access_token));
         session.m_session_has_been_bound = true;
     }
     if (session.m_deferred_commit_notification) {
         session.m_session->nonsync_transact_notify(*session.m_deferred_commit_notification);
         session.m_deferred_commit_notification = util::none;
     }
     session.advance_state(lock, active);
     if (session.m_deferred_close) {
         session.m_deferred_close = false;
         session.m_state->close(lock, session);
     }
 }
 void bind_with_admin_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                            const std::string& admin_token,
                            const std::string& server_url) const override
 {
     session.create_sync_session();
     session.advance_state(lock, waiting_for_access_token);
     session.m_state->refresh_access_token(lock, session, admin_token, server_url);
 }
 bool access_token_expired(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, waiting_for_access_token);
     std::shared_ptr<SyncSession> session_ptr = session.shared_from_this();
     lock.unlock();
     session.m_config.bind_session_handler(session_ptr->m_realm_path, session_ptr->m_config, session_ptr);
     return false;
 }
 void enter_state(std::unique_lock<std::mutex>&, SyncSession& session) const override
 {
     size_t current_death_count = ++session.m_death_count;
     session.m_session->async_wait_for_upload_completion([session=&session, current_death_count](std::error_code) {
         std::unique_lock<std::mutex> lock(session->m_state_mutex);
         if (session->m_state == &State::dying && session->m_death_count == current_death_count) {
             session->advance_state(lock, inactive);
         }
     });
 }
Example #7
0
    void enter_state(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
    {
        // If we have no session, we cannot possibly upload anything.
        if (!session.m_session) {
            session.advance_state(lock, inactive);
            return;
        }

        size_t current_death_count = ++session.m_death_count;
        std::weak_ptr<SyncSession> weak_session = session.shared_from_this();
        session.m_session->async_wait_for_upload_completion([weak_session, current_death_count](std::error_code) {
            if (auto session = weak_session.lock()) {
                std::unique_lock<std::mutex> lock(session->m_state_mutex);
                if (session->m_state == &State::dying && session->m_death_count == current_death_count) {
                    session->advance_state(lock, inactive);
                }
            }
        });
    }
Example #8
0
 bool handle_error(std::unique_lock<std::mutex>& lock, SyncSession& session, const SyncError& error) const override
 {
     if (error.is_fatal) {
         session.advance_state(lock, inactive);
     }
     // If the error isn't fatal, don't change state, but don't
     // allow it to be reported either.
     // FIXME: What if the token expires while a session is dying?
     // Should we allow the token to be refreshed so that changes
     // can finish being uploaded?
     return true;
 }
Example #9
0
 void close(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     switch (session.m_config.stop_policy) {
         case SyncSessionStopPolicy::Immediately:
             // Immediately kill the session.
             session.advance_state(lock, inactive);
             break;
         case SyncSessionStopPolicy::LiveIndefinitely:
         case SyncSessionStopPolicy::AfterChangesUploaded:
             // Defer handling closing the session until after the login response succeeds.
             session.m_deferred_close = true;
             break;
     }
 }
Example #10
0
    void enter_state(std::unique_lock<std::mutex>&, SyncSession& session) const override
    {
        ++session.m_pending_upload_threads;
        std::thread([session=&session] {
            std::unique_lock<std::mutex> lock(session->m_state_mutex);
            if (session->m_pending_upload_threads != 1) {
                --session->m_pending_upload_threads;
                return;
            }

            if (session->m_state != &State::dying) {
                // The session was revived. Don't kill it.
                --session->m_pending_upload_threads;
                return;
            }

            session->m_session->wait_for_upload_complete_or_client_stopped();
            --session->m_pending_upload_threads;
            session->advance_state(lock, inactive);
        }).detach();
    }
Example #11
0
    void refresh_access_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                              std::string access_token,
                              const util::Optional<std::string>& server_url) const override
    {
        session.create_sync_session();

        // Since the sync session was previously unbound, it's safe to do this from the
        // calling thread.
        if (!session.m_server_url) {
            session.m_server_url = server_url;
        }
        if (session.m_session_has_been_bound) {
            session.m_session->refresh(std::move(access_token));
            session.m_session->cancel_reconnect_delay();
        } else {
            session.m_session->bind(*session.m_server_url, std::move(access_token));
            session.m_session_has_been_bound = true;
        }

        if (session.m_server_override)
            session.m_session->override_server(session.m_server_override->address, session.m_server_override->port);

        // Register all the pending wait-for-completion blocks.
        for (auto& package : session.m_completion_wait_packages) {
            (*session.m_session.*package.waiter)(std::move(package.callback));
        }
        session.m_completion_wait_packages.clear();

        // Handle any deferred commit notification.
        if (session.m_deferred_commit_notification) {
            session.m_session->nonsync_transact_notify(*session.m_deferred_commit_notification);
            session.m_deferred_commit_notification = util::none;
        }

        session.advance_state(lock, active);
        if (session.m_deferred_close) {
            session.m_state->close(lock, session);
        }
    }
 void log_out(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, inactive);
 }
 bool revive_if_needed(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Revive.
     session.advance_state(lock, active);
     return false;
 }
 void close_if_connecting(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Ignore the sync configuration's stop policy as we're not yet connected.
     session.advance_state(lock, inactive);
 }
Example #15
0
 void access_token_expired(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, waiting_for_access_token);
 }