Skip to content

Commit 02b283b

Browse files
Bug 2019049 - Use a [Trait, WithForeign] interface for GeckoPrefHandler (#7433)
Additionally I rooted out the unneeded transmutes: since we've got an `Arc<>`, we can already clone it and `Arc<T>` will cast to `Arc<dyn Interface>` for `T: Interface`.
1 parent ab63744 commit 02b283b

8 files changed

Lines changed: 31 additions & 112 deletions

File tree

components/nimbus/src/enrollment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ where
13611361

13621362
pub(crate) fn sort_experiments_by_published_date(experiments: &[Experiment]) -> Vec<&Experiment> {
13631363
let mut experiments: Vec<_> = experiments.iter().collect();
1364-
experiments.sort_by(|a, b| a.published_date.cmp(&b.published_date));
1364+
experiments.sort_by_key(|e| e.published_date);
13651365
experiments
13661366
}
13671367

components/nimbus/src/nimbus.udl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,14 @@ dictionary MalformedFeatureConfigExtraDef {
147147
string part;
148148
};
149149

150-
callback interface GeckoPrefHandler {
150+
[Trait, WithForeign]
151+
interface GeckoPrefHandler {
151152
record<string, record<string, GeckoPrefState>> get_prefs_with_state();
152153

153154
void set_gecko_prefs_state(sequence<GeckoPrefState> new_prefs_state);
154155

155156
void set_gecko_prefs_original_values(sequence<OriginalGeckoPref> original_gecko_prefs);
156-
157+
157158
};
158159

159160
dictionary GeckoPref {

components/nimbus/src/stateful/gecko_prefs.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ pub fn create_feature_prop_pref_map(
125125
)
126126
}
127127

128+
#[uniffi::trait_interface]
128129
pub trait GeckoPrefHandler: Send + Sync {
129130
/// Used to obtain the prefs values from Gecko
130131
fn get_prefs_with_state(&self) -> MapOfFeatureIdToPropertyNameToGeckoPrefState;
@@ -161,12 +162,12 @@ impl GeckoPrefStoreState {
161162

162163
pub struct GeckoPrefStore {
163164
// This is Arc<Box<_>> because of FFI
164-
pub handler: Arc<Box<dyn GeckoPrefHandler>>,
165+
pub handler: Arc<dyn GeckoPrefHandler>,
165166
pub state: Mutex<GeckoPrefStoreState>,
166167
}
167168

168169
impl GeckoPrefStore {
169-
pub fn new(handler: Arc<Box<dyn GeckoPrefHandler>>) -> Self {
170+
pub fn new(handler: Arc<dyn GeckoPrefHandler>) -> Self {
170171
Self {
171172
handler,
172173
state: Mutex::new(GeckoPrefStoreState::default()),

components/nimbus/src/stateful/nimbus_client.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use crate::stateful::targeting::{RecordedContext, validate_event_queries};
5252
use crate::stateful::updating::{read_and_remove_pending_experiments, write_pending_experiments};
5353
use crate::strings::fmt_with_map;
5454
#[cfg(test)]
55-
use crate::tests::helpers::{TestGeckoPrefHandler, TestRecordedContext};
55+
use crate::tests::helpers::TestRecordedContext;
5656
use crate::{
5757
AvailableExperiment, AvailableRandomizationUnits, EnrolledExperiment, EnrollmentStatus,
5858
};
@@ -113,7 +113,7 @@ impl NimbusClient {
113113
coenrolling_feature_ids: Vec<String>,
114114
db_path: P,
115115
metrics_handler: Arc<dyn MetricsHandler>,
116-
gecko_pref_handler: Option<Box<dyn GeckoPrefHandler>>,
116+
gecko_pref_handler: Option<Arc<dyn GeckoPrefHandler>>,
117117
remote_settings_info: Option<NimbusServerSettings>,
118118
) -> Result<Self> {
119119
let settings_client = Mutex::new(create_client(remote_settings_info)?);
@@ -128,7 +128,7 @@ impl NimbusClient {
128128

129129
let mut prefs = None;
130130
if let Some(handler) = gecko_pref_handler {
131-
prefs = Some(Arc::new(GeckoPrefStore::new(Arc::new(handler))));
131+
prefs = Some(Arc::new(GeckoPrefStore::new(handler)));
132132
}
133133

134134
info!(
@@ -930,23 +930,6 @@ impl NimbusClient {
930930
.expect("failed to unwrap RecordedContext object")
931931
}
932932

933-
#[cfg(test)]
934-
pub fn get_gecko_pref_store(&self) -> Arc<Box<TestGeckoPrefHandler>> {
935-
self.gecko_prefs.clone()
936-
.clone()
937-
.map(|ref pref_store|
938-
// SAFETY: The cast to TestGeckoPrefHandler is safe because the Rust instance is
939-
// guaranteed to be a TestGeckoPrefHandler instance. TestGeckoPrefHandler is the only
940-
// Rust-implemented version of GeckoPrefHandler, and, like this method, is only
941-
// used in tests.
942-
unsafe {
943-
std::mem::transmute::<Arc<Box<dyn GeckoPrefHandler>>, Arc<Box<TestGeckoPrefHandler>>>(
944-
pref_store.clone().handler.clone(),
945-
)
946-
})
947-
.expect("failed to unwrap GeckoPrefHandler object")
948-
}
949-
950933
pub fn set_install_time(&mut self, then: DateTime<Utc>) {
951934
let mut state = self.mutable_state.lock().unwrap();
952935
state.install_date = Some(then);

components/nimbus/src/tests/helpers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,15 @@ pub struct TestGeckoPrefHandler {
189189

190190
#[cfg(feature = "stateful")]
191191
impl TestGeckoPrefHandler {
192-
pub(crate) fn new(prefs: MapOfFeatureIdToPropertyNameToGeckoPrefState) -> Self {
193-
Self {
192+
pub(crate) fn new(prefs: MapOfFeatureIdToPropertyNameToGeckoPrefState) -> Arc<Self> {
193+
Arc::new(Self {
194194
prefs,
195195
state: Mutex::new(TestGeckoPrefHandlerState {
196196
prefs_set: None,
197197
original_prefs_state: None,
198198
set_gecko_prefs_state_call_count: 0,
199199
}),
200-
}
200+
})
201201
}
202202
}
203203

components/nimbus/src/tests/stateful/test_gecko_prefs.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ fn test_gecko_pref_store_map_gecko_prefs_to_enrollment_slugs_and_update_store()
2525
"test_prop",
2626
pref_state.clone(),
2727
)]));
28-
let handler: Arc<Box<dyn GeckoPrefHandler>> = Arc::new(Box::new(handler));
2928
let store = GeckoPrefStore::new(handler.clone());
3029
store.initialize()?;
3130

@@ -60,11 +59,6 @@ fn test_gecko_pref_store_map_gecko_prefs_to_enrollment_slugs_and_update_store()
6059
true,
6160
);
6261

63-
let handler = unsafe {
64-
std::mem::transmute::<Arc<Box<dyn GeckoPrefHandler>>, Arc<Box<TestGeckoPrefHandler>>>(
65-
handler,
66-
)
67-
};
6862
let handler_state = handler
6963
.state
7064
.lock()
@@ -91,7 +85,6 @@ fn test_gecko_pref_store_map_gecko_prefs_to_enrollment_slugs_and_update_store_ex
9185
"test_prop",
9286
pref_state.clone(),
9387
)]));
94-
let handler: Arc<Box<dyn GeckoPrefHandler>> = Arc::new(Box::new(handler));
9588
let store = GeckoPrefStore::new(handler.clone());
9689
store.initialize()?;
9790

@@ -154,11 +147,6 @@ fn test_gecko_pref_store_map_gecko_prefs_to_enrollment_slugs_and_update_store_ex
154147
true,
155148
);
156149

157-
let handler = unsafe {
158-
std::mem::transmute::<Arc<Box<dyn GeckoPrefHandler>>, Arc<Box<TestGeckoPrefHandler>>>(
159-
handler,
160-
)
161-
};
162150
let handler_state = handler
163151
.state
164152
.lock()
@@ -215,7 +203,6 @@ fn test_gecko_pref_store_pref_is_user_set() -> Result<()> {
215203
("test_feature", "test_prop_1", pref_state_1.clone()),
216204
("test_feature", "test_prop_2", pref_state_2.clone()),
217205
]));
218-
let handler: Arc<Box<dyn GeckoPrefHandler>> = Arc::new(Box::new(handler));
219206
let store = GeckoPrefStore::new(handler.clone());
220207
store.initialize()?;
221208

@@ -380,17 +367,11 @@ fn test_set_gecko_prefs_original_values() {
380367
"test_prop",
381368
pref_state_1.clone(),
382369
)]));
383-
let handler: Arc<Box<dyn GeckoPrefHandler>> = Arc::new(Box::new(handler));
384370
let store = Arc::new(GeckoPrefStore::new(handler.clone()));
385371
let _ = store.initialize();
386372

387373
handler.set_gecko_prefs_original_values(original_gecko_prefs.clone());
388-
let test_handler = unsafe {
389-
std::mem::transmute::<Arc<Box<dyn GeckoPrefHandler>>, Arc<Box<TestGeckoPrefHandler>>>(
390-
handler,
391-
)
392-
};
393-
let test_handler_state = test_handler
374+
let test_handler_state = handler
394375
.state
395376
.lock()
396377
.expect("Unable to lock transmuted handler state");

components/nimbus/src/tests/stateful/test_nimbus.rs

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,7 +1796,7 @@ fn test_gecko_pref_enrollment() -> Result<()> {
17961796
Default::default(),
17971797
temp_dir.path(),
17981798
TestMetrics::new(),
1799-
Some(Box::new(handler)),
1799+
Some(handler.clone()),
18001800
None,
18011801
)?;
18021802
client.set_nimbus_id(&Uuid::from_str("00000000-0000-0000-0000-000000000004")?)?;
@@ -1820,11 +1820,7 @@ fn test_gecko_pref_enrollment() -> Result<()> {
18201820
let active_experiments = client.get_active_experiments()?;
18211821
assert_eq!(active_experiments.len(), 1);
18221822

1823-
let handler = client.get_gecko_pref_store();
1824-
let handler_state = handler
1825-
.state
1826-
.lock()
1827-
.expect("Unable to lock transmuted handler state");
1823+
let handler_state = handler.state.lock().expect("Unable to lock handler state");
18281824
let prefs = handler_state.prefs_set.clone().unwrap();
18291825

18301826
assert_eq!(1, prefs.len());
@@ -1872,7 +1868,7 @@ fn test_gecko_pref_unenrollment() -> Result<()> {
18721868
Default::default(),
18731869
temp_dir.path(),
18741870
TestMetrics::new(),
1875-
Some(Box::new(handler)),
1871+
Some(handler.clone()),
18761872
None,
18771873
)?;
18781874
client.set_nimbus_id(&Uuid::from_str("00000000-0000-0000-0000-000000000004")?)?;
@@ -1910,11 +1906,7 @@ fn test_gecko_pref_unenrollment() -> Result<()> {
19101906
assert_eq!(active_experiments.len(), 2);
19111907

19121908
{
1913-
let handler = client.get_gecko_pref_store();
1914-
let handler_state = handler
1915-
.state
1916-
.lock()
1917-
.expect("Unable to lock transmuted handler state");
1909+
let handler_state = handler.state.lock().expect("Unable to lock handler state");
19181910
let prefs = handler_state.prefs_set.clone().unwrap();
19191911

19201912
assert_eq!(1, prefs.len());
@@ -1959,11 +1951,7 @@ fn test_gecko_pref_unenrollment() -> Result<()> {
19591951
assert_eq!(active_experiments.len(), 0);
19601952

19611953
{
1962-
let handler = client.get_gecko_pref_store();
1963-
let handler_state = handler
1964-
.state
1965-
.lock()
1966-
.expect("Unable to lock transmuted handler state");
1954+
let handler_state = handler.state.lock().expect("Unable to lock handler state");
19671955
let prefs = handler_state.prefs_set.clone().unwrap();
19681956

19691957
assert_eq!(0, prefs.len());
@@ -2006,7 +1994,7 @@ fn test_gecko_pref_unenrollment_reverts() -> Result<()> {
20061994
Default::default(),
20071995
temp_dir.path(),
20081996
TestMetrics::new(),
2009-
Some(Box::new(handler)),
1997+
Some(handler.clone()),
20101998
None,
20111999
)?;
20122000
client.set_nimbus_id(&Uuid::from_str("00000000-0000-0000-0000-000000000004")?)?;
@@ -2060,11 +2048,7 @@ fn test_gecko_pref_unenrollment_reverts() -> Result<()> {
20602048
assert_eq!(active_experiments.len(), 2);
20612049

20622050
{
2063-
let handler = client.get_gecko_pref_store();
2064-
let handler_state = handler
2065-
.state
2066-
.lock()
2067-
.expect("Unable to lock transmuted handler state");
2051+
let handler_state = handler.state.lock().expect("Unable to lock handler state");
20682052
let prefs = handler_state.prefs_set.clone().unwrap();
20692053

20702054
assert_eq!(2, prefs.len());
@@ -2110,11 +2094,7 @@ fn test_gecko_pref_unenrollment_reverts() -> Result<()> {
21102094
assert_eq!(active_experiments.len(), 0);
21112095

21122096
{
2113-
let handler = client.get_gecko_pref_store();
2114-
let handler_state = handler
2115-
.state
2116-
.lock()
2117-
.expect("Unable to lock transmuted handler state");
2097+
let handler_state = handler.state.lock().expect("Unable to lock handler state");
21182098

21192099
let original_prefs_stored = handler_state.original_prefs_state.clone().unwrap();
21202100

@@ -2151,7 +2131,7 @@ fn register_previous_gecko_pref_states() -> Result<()> {
21512131
Default::default(),
21522132
temp_dir.path(),
21532133
metrics.clone(),
2154-
Some(Box::new(handler)),
2134+
Some(handler.clone()),
21552135
None,
21562136
)?;
21572137
client.set_nimbus_id(&Uuid::from_str("00000000-0000-0000-0000-000000000004")?)?;
@@ -2245,8 +2225,7 @@ fn register_previous_gecko_pref_states() -> Result<()> {
22452225
gecko_pref_state_3.clone(),
22462226
];
22472227

2248-
let call_count_before = client
2249-
.get_gecko_pref_store()
2228+
let call_count_before = handler
22502229
.state
22512230
.lock()
22522231
.unwrap()
@@ -2258,8 +2237,7 @@ fn register_previous_gecko_pref_states() -> Result<()> {
22582237
// Registration must not send pref values to Gecko.
22592238
assert_eq!(
22602239
call_count_before,
2261-
client
2262-
.get_gecko_pref_store()
2240+
handler
22632241
.state
22642242
.lock()
22652243
.unwrap()
@@ -2350,7 +2328,7 @@ fn test_add_prev_gecko_pref_states_for_experiment() -> Result<()> {
23502328
Default::default(),
23512329
temp_dir.path(),
23522330
metrics.clone(),
2353-
Some(Box::new(handler)),
2331+
Some(handler),
23542332
None,
23552333
)?;
23562334
client.set_nimbus_id(&Uuid::from_str("00000000-0000-0000-0000-000000000004")?)?;

0 commit comments

Comments
 (0)