fix(servo): lease persistent profile data
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
fs::{self, File, OpenOptions, TryLockError},
|
||||
io::{self, BufRead},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use ely_domain::{ProfileId, TabId, UrlText};
|
||||
@@ -24,9 +25,12 @@ use super::{
|
||||
},
|
||||
};
|
||||
|
||||
const PROFILE_DATA_LEASE_FILE: &str = ".ely-servo-sidecar.lock";
|
||||
|
||||
pub(super) fn run(args: LiveArgs) -> Result<(), LiveSidecarError> {
|
||||
let LiveArgs { profile_data_dir, rendering_context, iosurface_mach_service } = args;
|
||||
fs::create_dir_all(&profile_data_dir)?;
|
||||
let _profile_data_lease = acquire_profile_data_lease(&profile_data_dir)?;
|
||||
let rendering_context_kind = match rendering_context {
|
||||
SidecarRenderingContext::Software => RenderingContextKind::Software,
|
||||
SidecarRenderingContext::Hardware => RenderingContextKind::Hardware,
|
||||
@@ -84,6 +88,22 @@ pub(super) fn run(args: LiveArgs) -> Result<(), LiveSidecarError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn acquire_profile_data_lease(profile_data_dir: &Path) -> Result<File, LiveSidecarError> {
|
||||
let lease = OpenOptions::new()
|
||||
.create(true)
|
||||
.read(true)
|
||||
.write(true)
|
||||
.truncate(false)
|
||||
.open(profile_data_dir.join(PROFILE_DATA_LEASE_FILE))?;
|
||||
match lease.try_lock() {
|
||||
Ok(()) => Ok(lease),
|
||||
Err(TryLockError::WouldBlock) => Err(LiveSidecarError::ProfileDataDirectoryInUse {
|
||||
path: profile_data_dir.to_path_buf(),
|
||||
}),
|
||||
Err(TryLockError::Error(error)) => Err(error.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_request(
|
||||
host: &mut SoftwareServoHost,
|
||||
sessions: &mut HashMap<String, LiveSession>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
use ely_servo_host::{
|
||||
ConsumedPermission, IOSurfaceHandle, RenderedFrame, ServoHostError, WebViewSnapshot,
|
||||
@@ -305,6 +305,9 @@ pub(super) enum LiveSidecarError {
|
||||
#[error("sidecar process is already bound to profile {expected}; received {actual}")]
|
||||
ProfileMismatch { expected: String, actual: String },
|
||||
|
||||
#[error("servo profile data directory is already in use: {path}")]
|
||||
ProfileDataDirectoryInUse { path: PathBuf },
|
||||
|
||||
#[error("{input} requires both x and y coordinates")]
|
||||
IncompletePoint { input: &'static str },
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
use std::{
|
||||
error::Error,
|
||||
io, thread,
|
||||
io,
|
||||
process::{Command, Stdio},
|
||||
thread,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
@@ -64,6 +66,38 @@ fn live_sidecar_streams_rgba_and_flushes_profile_storage_on_shutdown() -> Result
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn live_sidecar_leases_profile_data_directory_for_process_lifetime() -> Result<(), Box<dyn Error>> {
|
||||
let root = TestDirectory::new()?;
|
||||
let leased_dir = root.path().join("leased");
|
||||
let independent_dir = root.path().join("independent");
|
||||
let mut owner = Sidecar::spawn(&leased_dir)?;
|
||||
assert!(leased_dir.join(".ely-servo-sidecar.lock").is_file());
|
||||
|
||||
let rejected = Command::new(env!("CARGO_BIN_EXE_ely_servo_sidecar"))
|
||||
.arg("live")
|
||||
.arg("--profile-data-dir")
|
||||
.arg(&leased_dir)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::piped())
|
||||
.output()?;
|
||||
let stderr = String::from_utf8(rejected.stderr)?;
|
||||
assert!(!rejected.status.success(), "second sidecar unexpectedly acquired the profile lease");
|
||||
assert!(
|
||||
stderr.contains("ProfileDataDirectoryInUse"),
|
||||
"second sidecar reported an unexpected error: {stderr}"
|
||||
);
|
||||
|
||||
let mut independent = Sidecar::spawn(&independent_dir)?;
|
||||
independent.shutdown()?;
|
||||
owner.shutdown()?;
|
||||
|
||||
let mut replacement = Sidecar::spawn(&leased_dir)?;
|
||||
replacement.shutdown()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn servo_originated_history_url_does_not_trigger_a_second_navigation() -> Result<(), Box<dyn Error>>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user