interop peers: hold-lock mode in the C# peer and the Rust example

Each holds <file>.lock by its own runtime's protocol (share-none open; fs2 exclusive),
prints {"held":true}, sleeps --ms, releases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-20 14:50:19 +02:00
commit 3cd9880c04
2 changed files with 36 additions and 2 deletions

View file

@ -30,18 +30,35 @@ fn main() -> Result<()> {
let mut args = std::env::args().skip(1);
let mode = args
.next()
.ok_or_else(|| anyhow!("expected mode: write | read"))?;
.ok_or_else(|| anyhow!("expected mode: write | read | hold-lock"))?;
let options = parse_args(args.collect());
let file = require_arg(&options, "file")?;
match mode.as_str() {
"write" => write_note(file, require_arg(&options, "runtime-id")?)?,
"read" => read_note(file)?,
"hold-lock" => hold_lock(file, require_arg(&options, "ms")?.parse()?)?,
_ => return Err(anyhow!("unknown mode {mode}")),
}
Ok(())
}
/// Holds the store lock as the library opens it (`<file>.lock`, fs2 exclusive), for `ms`.
fn hold_lock(file: &str, ms: u64) -> Result<()> {
let lock = std::fs::OpenOptions::new()
.create(true)
.read(true)
.truncate(false)
.write(true)
.open(format!("{file}.lock"))?;
fs2::FileExt::lock_exclusive(&lock)?;
println!("{}", json!({ "held": true }));
std::io::Write::flush(&mut std::io::stdout())?;
std::thread::sleep(std::time::Duration::from_millis(ms));
fs2::FileExt::unlock(&lock)?;
Ok(())
}
fn write_note(file: &str, runtime_id: &str) -> Result<()> {
let mut cache = build_cache(file)?;
cache.pull_all_backing_stores()?;

View file

@ -16,7 +16,7 @@ static async Task<int> ProgramMainAsync(string[] args)
{
if (args.Length == 0)
{
throw new InvalidOperationException("Expected mode: write | read | write-routed <catalog.cc> <run.cc>");
throw new InvalidOperationException("Expected mode: write | read | hold-lock | write-routed <catalog.cc> <run.cc>");
}
var mode = args[0];
@ -38,6 +38,9 @@ static async Task<int> ProgramMainAsync(string[] args)
case "read":
await ReadAsync(file);
return 0;
case "hold-lock":
HoldLock(file, int.Parse(RequireArg(options, "ms"), CultureInfo.InvariantCulture));
return 0;
default:
throw new InvalidOperationException($"Unknown mode {mode}.");
}
@ -49,6 +52,20 @@ static async Task<int> ProgramMainAsync(string[] args)
}
}
// Holds the store lock exactly as CultCache.AcquireLock opens it, for --ms, then releases it.
static void HoldLock(string file, int milliseconds)
{
using var held = new System.IO.FileStream(
file + ".lock",
System.IO.FileMode.OpenOrCreate,
System.IO.FileAccess.ReadWrite,
System.IO.FileShare.None,
bufferSize: 1);
Console.WriteLine("{\"held\":true}");
Console.Out.Flush();
System.Threading.Thread.Sleep(milliseconds);
}
static async Task WriteAsync(string file, string runtimeId)
{
var cache = BuildCache(file);