feat: send current_patch_number on patch check (#343)
* feat: send current patch_number on patch check * refactor: rename patch_number → current_patch_number Renaming the field on PatchCheckRequest so it doesn't collide with the legacy `patch_number` field old pre-#189 updaters still send. That legacy field is what triggers the server's short-circuit response (patchAvailable: false, no rolled_back_patch_numbers), which is still load-bearing for ~0.7% of patch-check traffic coming from Flutter ≤ 3.22.2 clients. Using a distinct field name keeps our new analytics signal from accidentally engaging that path. Pairs with: - shorebirdtech/shorebird#3702 (protocol field) - shorebirdtech/_shorebird#2059 (server consumes this field) * docs: rephrase current_patch_number doc comment Drops the 'analytics' framing in favor of describing the field as superseding patch_number for newer clients. patch_number remains for compatibility with legacy clients that rely on the short-circuit path. * fix: adapt to renamed currently_booting_patch and &str client_id
This commit is contained in:
+15
-3
@@ -247,12 +247,22 @@ pub struct PatchCheckRequest {
|
||||
/// The unique ID of this device. This is a random UUID generated by Shorebird and _not_ the
|
||||
/// device's UUID or any other identifier that has meaning outside of Shorebird.
|
||||
pub client_id: String,
|
||||
// We specifically do not send a patch number as part of this request because we always want to
|
||||
// know what the latest available patch is.
|
||||
/// The number of the patch currently running on the device, if any.
|
||||
///
|
||||
/// Supersedes the legacy `patch_number` field. `patch_number` is
|
||||
/// retained server-side for compatibility with older clients that still
|
||||
/// rely on its short-circuit response path; newer updaters populate
|
||||
/// this field instead.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub current_patch_number: Option<usize>,
|
||||
}
|
||||
|
||||
impl PatchCheckRequest {
|
||||
pub fn new(config: &UpdateConfig, client_id: &str) -> PatchCheckRequest {
|
||||
pub fn new(
|
||||
config: &UpdateConfig,
|
||||
client_id: &str,
|
||||
current_patch_number: Option<usize>,
|
||||
) -> PatchCheckRequest {
|
||||
PatchCheckRequest {
|
||||
app_id: config.app_id.clone(),
|
||||
channel: config.channel.clone(),
|
||||
@@ -260,6 +270,7 @@ impl PatchCheckRequest {
|
||||
platform: current_platform().to_string(),
|
||||
arch: current_arch().to_string(),
|
||||
client_id: client_id.to_string(),
|
||||
current_patch_number,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,6 +415,7 @@ mod tests {
|
||||
platform: "".to_string(),
|
||||
arch: "".to_string(),
|
||||
client_id: "".to_string(),
|
||||
current_patch_number: None,
|
||||
},
|
||||
);
|
||||
assert!(result.is_err());
|
||||
|
||||
+12
-3
@@ -273,7 +273,12 @@ pub fn should_auto_update() -> anyhow::Result<bool> {
|
||||
/// Returns true if an update is available for download. Will return false if the update is already
|
||||
/// downloaded and ready to install.
|
||||
pub fn check_for_downloadable_update(channel: Option<&str>) -> anyhow::Result<bool> {
|
||||
let client_id = with_state(|state| Ok(state.client_id()))?;
|
||||
let (client_id, current_patch_number) = with_state(|state| {
|
||||
Ok((
|
||||
state.client_id().to_string(),
|
||||
state.currently_booting_patch().map(|p| p.number),
|
||||
))
|
||||
})?;
|
||||
|
||||
let (request, url, request_fn) = with_config(|config| {
|
||||
let mut config = config.clone();
|
||||
@@ -283,7 +288,7 @@ pub fn check_for_downloadable_update(channel: Option<&str>) -> anyhow::Result<bo
|
||||
}
|
||||
|
||||
Ok((
|
||||
PatchCheckRequest::new(&config, &client_id),
|
||||
PatchCheckRequest::new(&config, &client_id, current_patch_number),
|
||||
patches_check_url(&config.base_url),
|
||||
config.network_hooks.patch_check_request_fn,
|
||||
))
|
||||
@@ -400,7 +405,11 @@ fn update_internal(_: &UpdaterLockState, channel: Option<&str>) -> anyhow::Resul
|
||||
shorebird_error!("Failed to clear events: {:?}", err);
|
||||
}
|
||||
// Update our outer state with the new state.
|
||||
Ok(PatchCheckRequest::new(&config, &state.client_id()))
|
||||
Ok(PatchCheckRequest::new(
|
||||
&config,
|
||||
&state.client_id(),
|
||||
state.currently_booting_patch().map(|p| p.number),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Check for update.
|
||||
|
||||
Reference in New Issue
Block a user