| 26 | } |
| 27 | |
| 28 | pub fn pid_file(&self) -> Result<PidFile, PidFileError> { |
| 29 | use fs2::FileExt; |
| 30 | use io::{Read, Write}; |
| 31 | self.create()?; |
| 32 | let path = self.0.join("spacetime.pid"); |
| 33 | let mut file = fs::File::options() |
| 34 | .create(true) |
| 35 | .write(true) |
| 36 | .truncate(false) |
| 37 | .read(true) |
| 38 | .open(&path)?; |
| 39 | match file.try_lock_exclusive() { |
| 40 | Ok(()) => {} |
| 41 | Err(e) if e.kind() == io::ErrorKind::WouldBlock => { |
| 42 | let mut s = String::new(); |
| 43 | let pid = file.read_to_string(&mut s).ok().and_then(|_| s.trim().parse().ok()); |
| 44 | return Err(PidFileError::Exists { pid }); |
| 45 | } |
| 46 | Err(e) => return Err(e.into()), |
| 47 | } |
| 48 | let mut pidfile = PidFile { file, path }; |
| 49 | pidfile.file.set_len(0)?; |
| 50 | write!(pidfile.file, "{}", std::process::id())?; |
| 51 | pidfile.file.flush()?; |
| 52 | pidfile.file.sync_data()?; |
| 53 | |
| 54 | Ok(pidfile) |
| 55 | } |
| 56 | |
| 57 | pub fn replica(&self, replica_id: u64) -> ReplicaDir { |
| 58 | ReplicaDir(self.0.join("replicas").joined_int(replica_id)) |