forked from jess/Acord
1
0
Fork 0

Fix excessive writing to disk by gating r/w behind in-mem hash checks first.

This commit is contained in:
jess 2026-04-18 14:19:35 -07:00
parent 9c0a74c1ce
commit 035164a698
2 changed files with 33 additions and 0 deletions

View File

@ -32,6 +32,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuItemValidation {
/// eval overlay. By writing straight to disk, autosave can't disturb
/// what the user sees.
private var autosaveTimer: Timer?
/// Hash of the viewport text the last time autosave actually wrote to
/// disk. The 100ms timer compares against this and skips the write if
/// nothing has changed without this gate, autosave rewrites the
/// entire file every tick (~500 KB/s sustained on a 50 KB doc, which
/// macOS flags as a disk-writes throttle event).
private var lastAutosavedHash: Int?
private var viewport: IcedViewportView? {
window?.contentView as? IcedViewportView
@ -719,7 +725,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuItemValidation {
guard let w = window, let vp = w.contentView as? IcedViewportView else { return }
let text = vp.getText()
guard !AppState.isEffectivelyBlank(text) else { return }
let hash = text.hashValue
if hash == lastAutosavedHash { return }
appState.writeAutosavedCopy(text: text)
lastAutosavedHash = hash
}
private func observeDocumentTitle() {

View File

@ -48,6 +48,29 @@ pub struct ViewportHandle {
pub needs_redraw: bool,
}
/// Install a panic hook that flushes a full backtrace to stderr before
/// the process aborts. Called once on first viewport_create. Without this
/// the host (Swift / winit) often eats the panic message and the user sees
/// only a silent SIGABRT with no `.ips` file.
fn install_panic_hook() {
use std::sync::Once;
static ONCE: Once = Once::new();
ONCE.call_once(|| {
let prior = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
use std::io::Write;
let mut err = std::io::stderr().lock();
let _ = writeln!(err, "===== ACORD RUST PANIC =====");
let _ = writeln!(err, "{}", info);
let bt = std::backtrace::Backtrace::force_capture();
let _ = writeln!(err, "{}", bt);
let _ = writeln!(err, "============================");
let _ = err.flush();
prior(info);
}));
});
}
#[unsafe(no_mangle)]
pub extern "C" fn viewport_create(
nsview: *mut c_void,
@ -55,6 +78,7 @@ pub extern "C" fn viewport_create(
height: f32,
scale: f32,
) -> *mut ViewportHandle {
install_panic_hook();
if nsview.is_null() {
return std::ptr::null_mut();
}