Bug 2054982 - Finer grained locking for RemoteSettingService - #7474
Conversation
gruberb
left a comment
There was a problem hiding this comment.
I think we have to(please double check) combine creating the config and registering the client into one operation not to get out of sync. We can keep sync_client separate not to be blocking.
struct RemoteSettingsService {
storage_dir: Utf8PathBuf,
// Short-lived lock: configuration and client registration.
state: Mutex<RemoteSettingsServiceState>,
// Long-lived lock: held across the monitoring network request.
sync_client: Mutex<RemoteSettingsServiceSyncClient>,
telemetry: Mutex<RemoteSettingsTelemetryWrapper>,
}
struct RemoteSettingsServiceState {
config: RemoteSettingsServiceConfig,
clients: Vec<Weak<RemoteSettingsClient>>,
}| let config = self.clone_config(); | ||
| let client = Arc::new(RemoteSettingsClient::new( | ||
| inner.base_url.clone(), | ||
| inner.bucket_name.clone(), | ||
| config.base_url, | ||
| config.bucket_name, | ||
| collection_name.clone(), | ||
| inner.app_context.clone(), | ||
| config.app_context.clone(), | ||
| storage, | ||
| )); | ||
| inner.clients.push(Arc::downgrade(&client)); | ||
| self.push_client(Arc::downgrade(&client)); |
There was a problem hiding this comment.
Could make_client() race with update_config() here? clone_config() releases the config lock before this client is added to clients. If update_config() runs between these calls, active_clients() won’t include the new client, but the service config will be replaced. The client can then be registered with the old config and never receive the update.
Could config access and client registration/update share one short-lived mutex-protected state? sync_client could remain separate, so this would not reintroduce the original network-blocking issue.
There was a problem hiding this comment.
Oh yes it could indeed, nice catch.
There was a problem hiding this comment.
I followed your suggestion and put everything in one mutex and changed make_client to hold the mutex for the entire operation (which should be quick).
d924c1f to
58dc98d
Compare
gruberb
left a comment
There was a problem hiding this comment.
I am not 100% sure if that's the case, but I think the race technically still exists? The update_config() still acquires the lock twice? Could we have a helper function like
fn update_config_and_clients(&self, config: RemoteSettingsServiceConfig) {
let mut state = self.client_state.lock();
let active_clients = state.active_clients();
for client in active_clients {
client.internal.update_config(
config.base_url.clone(),
config.bucket_name.clone(),
config.app_context.clone(),
);
}
state.config = config;
}00fcbd4 to
63aa58a
Compare
Split up `RemoteSettingServiceInner` into multiple structs, each with their own Mutex and add a bit of policy around locking them. Right now this is just enforced by putting all the methods that lock them in one impl block. The issue we're trying to avoid is having `RemoteSettingService::sync` block `RemoteSettingService::make_client`. Also, start using `viaduct::Client` which should be possible now since all applications are using the new backend.
63aa58a to
77951a1
Compare
…#7474) Split up `RemoteSettingServiceInner` into multiple structs, each with their own Mutex and add a bit of policy around locking them. Right now this is just enforced by putting all the methods that lock them in one impl block. The issue we're trying to avoid is having `RemoteSettingService::sync` block `RemoteSettingService::make_client`. Also, start using `viaduct::Client` which should be possible now since all applications are using the new backend.
Split up
RemoteSettingServiceInnerinto multiple structs, each with their own Mutex and add a bit of policy around locking them. Right now this is just enforced by putting all the methods that lock them in one impl block.The issue we're trying to avoid is having
RemoteSettingService::syncblockRemoteSettingService::make_client.Also, start using
viaduct::Clientwhich should be possible now since all applications are using the new backend.Pull Request checklist
[ci full]to the PR title.