feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a finished pass, the child's credentials, the OpenRouter seats, and the board every driver on the machine shares, in one shape and under one lock. A driver is alive while its lifetime lock is held; with no lock file natively its pid and start time decide, and in the sandbox it is taken for alive. :Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is HttpError, every other failure carries a fixed text. :Platform gains MakeDirs, with the last directory's own mode, and errno texts for its writes and locks. The tests cover the seat pool and several drivers at once, less the checks that drive the pool's Scheduler, Admission and Stacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8ffbd6cf5d
commit
c63c898833
10 changed files with 2562 additions and 8 deletions
|
|
@ -169,7 +169,7 @@ namespace Crafter::Review::Platform {
|
|||
if (path.has_parent_path()) fs::create_directories(path.parent_path());
|
||||
const fs::path temp = std::format("{}.{}.tmp", path.string(), PublishedPid());
|
||||
const std::int32_t fd = open(temp.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, static_cast<mode_t>(mode));
|
||||
if (fd < 0) throw std::runtime_error(std::format("{}: {}", temp.string(), Dyn::ErrnoText(errno)));
|
||||
if (fd < 0) throw std::runtime_error(std::format("{}: {}", Dyn::ErrnoText(errno), Dyn::Repr(temp.string())));
|
||||
std::size_t written = 0;
|
||||
while (written < content.size()) {
|
||||
const ssize_t step = write(fd, content.data() + written, content.size() - written);
|
||||
|
|
@ -178,7 +178,7 @@ namespace Crafter::Review::Platform {
|
|||
const std::int32_t failure = errno;
|
||||
close(fd);
|
||||
unlink(temp.c_str());
|
||||
throw std::runtime_error(std::format("{}: {}", temp.string(), Dyn::ErrnoText(failure)));
|
||||
throw std::runtime_error(Dyn::ErrnoText(failure));
|
||||
}
|
||||
written += static_cast<std::size_t>(step);
|
||||
}
|
||||
|
|
@ -186,7 +186,21 @@ namespace Crafter::Review::Platform {
|
|||
if (rename(temp.c_str(), path.c_str()) != 0) {
|
||||
const std::int32_t failure = errno;
|
||||
unlink(temp.c_str());
|
||||
throw std::runtime_error(std::format("{}: {}", path.string(), Dyn::ErrnoText(failure)));
|
||||
throw std::runtime_error(std::format("{}: {} -> {}", Dyn::ErrnoText(failure), Dyn::Repr(temp.string()), Dyn::Repr(path.string())));
|
||||
}
|
||||
}
|
||||
|
||||
void MakeDirs(const fs::path& path, std::uint32_t mode) {
|
||||
const fs::path name = path.filename().empty() && path.has_parent_path() ? path.parent_path() : path;
|
||||
const fs::path head = name.parent_path();
|
||||
std::error_code error;
|
||||
if (!head.empty() && head != name && !fs::exists(head, error)) {
|
||||
MakeDirs(head, 0777);
|
||||
if (name.filename() == ".") return;
|
||||
}
|
||||
if (mkdir(name.c_str(), static_cast<mode_t>(mode)) != 0) {
|
||||
const std::int32_t failure = errno;
|
||||
if (!fs::is_directory(name, error)) throw std::runtime_error(std::format("{}: {}", Dyn::ErrnoText(failure), Dyn::Repr(name.string())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +209,7 @@ namespace Crafter::Review::Platform {
|
|||
if (lockPath.has_parent_path()) fs::create_directories(lockPath.parent_path(), error);
|
||||
fd = open(lockPath.c_str(), O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, 0666);
|
||||
if (fd < 0) {
|
||||
problem = Dyn::ErrnoText(errno);
|
||||
problem = std::format("{}: {}", Dyn::ErrnoText(errno), Dyn::Repr(lockPath.string()));
|
||||
return;
|
||||
}
|
||||
while (flock(fd, LOCK_EX) != 0) {
|
||||
|
|
@ -230,7 +244,7 @@ namespace Crafter::Review::Platform {
|
|||
}
|
||||
Json data;
|
||||
try {
|
||||
if (const std::optional<std::string> text = ReadFile(path)) data = Json::parse(*text);
|
||||
if (const std::optional<std::string> text = ReadFile(path)) data = ParseLoose(*text);
|
||||
} catch (const std::exception&) {
|
||||
data = Json();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue