Skip to content

Conversation

@jammel-yeboah
Copy link
Member

@jammel-yeboah jammel-yeboah commented Oct 24, 2025

Safe mode is a crucial mechanism for Cobalt to fall back to a "safe" or "default" config if it receives a faulty config that causes a crash.

If we crash 3 times, we fall back to the safe config. If we crash 4 times, we fall back to the default, or "empty" config.

It was recently discovered that Safe mode was not functioning in Cobalt. This PR fixes it.

bug: 452149713

}
}

void GlobalFeatures::Shutdown() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly destroys the metrics manager. This is then hooked into the application's main lifecycle by calling it from CobaltBrowserMainParts::PostMainMessageLoopRun()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good idea to surface this as a comment to make it clear for future maintainers

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Maybe add a comment explaining why we need to explicitly destroy it.

}
}

void GlobalFeatures::Shutdown() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good idea to surface this as a comment to make it clear for future maintainers

kEmptyConfig,
};

// This class manages the content of the experiment config stored on disk.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Probably worth updating this class' description since it is now doing extra work as tracking both experiment config and the state of the system (Crashes)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the class hasn't functionally changed. I discovered that it was checking the crash streak in the wrong file experiment_config, instead of metrics_local_state (see ExperimentConfigManager params). The class itself functionally remains the same 🙂

// the experiment config type.
experiment_config_manager_ =
std::make_unique<ExperimentConfigManager>(experiment_config_.get());
experiment_config_manager_ = std::make_unique<ExperimentConfigManager>(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super-nit: Since this is only used for initializing the activeExperimentIds consider moving it to the InitializeActiveExperimentIds function to keep all relevant steps around initializing experiments all together.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe setExperimentState also calls this config manager. I think it's ok either way (since this is a member variable) as long as the GlobalFeatures ctor initializes it

@jammel-yeboah jammel-yeboah marked this pull request as ready for review October 29, 2025 02:53
@jammel-yeboah jammel-yeboah requested a review from a team as a code owner October 29, 2025 02:53

#include "cobalt/browser/cobalt_content_browser_client.h"

#include <iostream>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove..?

// the experiment config type.
experiment_config_manager_ =
std::make_unique<ExperimentConfigManager>(experiment_config_.get());
experiment_config_manager_ = std::make_unique<ExperimentConfigManager>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe setExperimentState also calls this config manager. I think it's ok either way (since this is a member variable) as long as the GlobalFeatures ctor initializes it

}
}

void GlobalFeatures::Shutdown() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Maybe add a comment explaining why we need to explicitly destroy it.

// CommitPendingWrite not called here to avoid excessive disk writes.
// Features and featureParams won't be applied until the next Cobalt cold
// start so the delay is acceptable.
global_features->metrics_local_state()->CommitPendingWrite();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason we need to call CommitPendingWrite here?

void ClearMetricsServiceClientRawPtrForTest() { metrics_service_client_ = nullptr; }
void ClearMetricsServiceClient() { metrics_service_client_ = nullptr; }

void ClearMetricsServiceClientRawPtrForTest() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly is ClearMetricsServiceClientRawPtrForTest for? Are you planning to add tests in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was using this for debugging. Thanks for pointing it out, I'll remove it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants