AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Seastar
=======
Seastar is an event-driven framework that allows you to write non-blocking,
asynchronous code in a relatively straightforward manner (once understood).
It is based on futures.
For more details and alternative workflows, read HACKING.md.
Assuming that you would like to use system packages (RPMs or DEBs) for Seastar's dependencies, first install them:查看完整 README ↗Seastar is a C++ framework for writing high-performance server applications on modern multi-core hardware. It powers ScyllaDB, Redpanda, Ceph Crimson and other demanding systems.
Seastar is written in modern C++, and supports C++23 and C++26.
To build Seastar and use it in your own project, see BUILD.md.
Server frameworks have traditionally forced a choice between efficiency and the ability to build complex applications. Seastar aims for both: it lets you write large, complex servers while extracting the full performance of the hardware. Three principles make this possible:
Composable primitives. Everything that can take time is represented by the same abstraction, a future: reading from the network, writing to disk, waiting on a timer, running a function on another core, or even a long CPU-bound computation. These operations compose freely. A single coroutine can read a request from a socket, fan out to several disks and cores in parallel, wait for the results, and reply, all written as straight-line code.
Move operations to the data, not data to the operations. Seastar runs one thread per core (a shard) and partitions memory between them. Each piece of data is owned by a single shard; rather than locking the data and touching it from whichever core happens to need it, you send the operation to the shard that owns the data. There are no locks, no contended atomics and no cache-line bouncing on the fast path, so performance scales with the number of cores.
Symmetric architecture. All shards have the same role. There are no dedicated network threads, I/O threads or worker pools; every shard runs the full stack (networking, storage, application logic, and a cooperative scheduler) for its own slice of the data. Adding cores adds capacity uniformly, and the whole application is built from one kind of component, replicated.
co_await) are the recommended way to write new
code, and interoperate seamlessly with future-returning functions.seastar::sharded<T> instantiates a service on
every core and provides tools to invoke methods on one, some, or all
shards, and to map-reduce across them.parallel_for_each,
max_concurrent_for_each) and fork/join (coroutine::all).io_uring
or Linux AIO, with a scheduler that models the disk's capabilities (as
measured by iotune) to keep latency low while maximizing throughput.SEASTAR_TEST_CASE integration with Boost.Test for
writing asynchronous unit tests, a microbenchmark framework, and
allocation failure injection.This complete program starts an echo server on every core. Each shard listens on the same port, accepts its own connections, and serves each one concurrently in its own lightweight fiber.
#include <seastar/core/app-template.hh>
#include <seastar/core/coroutine.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/seastar.hh>
#include <seastar/core/sharded.hh>
#include <seastar/core/signal.hh>
#include <seastar/net/api.hh>
class echo_server {
seastar::server_socket _listener;
seastar::gate _gate;
public:
seastar::future<> start(uint16_t port) {
seastar::listen_options lo;
lo.reuse_address = true;
_listener = seastar::listen(seastar::make_ipv4_address({port}), lo);
(void)accept_loop(_gate.hold());
co_return;
}
seastar::future<> stop() {
_listener.abort_accept();
co_await _gate.close(); // wait for all connections to finish
}
private:
// Each fiber holds the gate open until it finishes.
seastar::future<> accept_loop(seastar::gate::holder) {
try {
while (true) {
auto [conn, addr] = co_await _listener.accept();
// Serve each connection concurrently, in its own fiber.
(void)handle(std::move(conn), _gate.hold());
}
} catch (...) {
// stop() called abort_accept()
}
}
seastar::future<> handle(seastar::connected_socket conn, seastar::gate::holder) {
auto in = conn.input();
auto out = conn.output();
try {
while (auto buf = co_await in.read()) {
co_await out.write(std::move(buf));
co_await out.flush();
}
} catch (...) {
// The client went away (e.g. reset the connection).
}
try {
co_await out.close();
} catch (...) {
// close() reports the same error again.
}
}
};
int main(int argc, char** argv) {
seastar::app_template app;
return app.run(argc, argv, [] () -> seastar::future<> {
seastar::sharded<echo_server> server;
co_await server.start(); // construct an echo_server on every shard
co_await server.invoke_on_all(&echo_server::start, uint16_t(1234));
seastar::promise<> stop_requested;
seastar::handle_signal(SIGINT, [&] { stop_requested.set_value(); }, true);
co_await stop_requested.get_future();
co_await server.stop(); // calls echo_server::stop() on every shard
});
}
co_await runs operations one after another. To overlap independent
operations, fork and join them:
#include <seastar/core/seastar.hh>
#include <seastar/coroutine/all.hh>
#include <seastar/coroutine/parallel_for_each.hh>
seastar::future<int> fetch(int key);
seastar::future<int> sum_two(int k1, int k2) {
// Both fetches run concurrently.
auto [a, b] = co_await seastar::coroutine::all(
[&] { return fetch(k1); },
[&] { return fetch(k2); });
co_return a + b;
}
seastar::future<uint64_t> total_size(std::vector<seastar::sstring> names) {
uint64_t total = 0;
// Stat all the files concurrently.
co_await seastar::coroutine::parallel_for_each(names, [&] (const seastar::sstring& name) -> seastar::future<> {
total += co_await seastar::file_size(name);
});
co_return total;
}
Shards share no state; they communicate by sending work to each other.
#include <functional>
#include <seastar/core/coroutine.hh>
#include <seastar/core/sharded.hh>
class counter {
uint64_t _hits = 0;
public:
void hit() { ++_hits; }
uint64_t hits() const { return _hits; }
seastar::future<> stop() { co_return; }
};
// Route each key to the shard that owns it.
seastar::future<> record(seastar::sharded<counter>& c, uint64_t key) {
co_await c.invoke_on(key % seastar::this_smp_shard_count(), [] (counter& local) {
local.hit();
});
}
// Gather a value from every shard.
seastar::future<uint64_t> total_hits(seastar::sharded<counter>& c) {
co_return co_await c.map_reduce0(
[] (const counter& local) { return local.hits(); },
uint64_t(0), std::plus<>());
}
Scheduling groups divide CPU and I/O between application components, and semaphores bound how much concurrency any one of them uses.
#include <seastar/core/scheduling.hh>
#include <seastar/core/semaphore.hh>
#include <seastar/coroutine/parallel_for_each.hh>
#include <seastar/coroutine/switch_to.hh>
seastar::future<> compact(table& t);
seastar::future<> compact_all(seastar::scheduling_group background, std::vector<table*> tables) {
// From here on, this coroutine runs with the background group's shares.
co_await seastar::coroutine::switch_to(background);
seastar::semaphore limit(4); // at most 4 compactions at a time
co_await seastar::coroutine::parallel_for_each(tables, [&] (table* t) -> seastar::future<> {
auto units = co_await seastar::get_units(limit, 1);
co_await compact(*t);
});
}
// Somewhere during startup:
// auto background = co_await seastar::create_scheduling_group("compaction", 100);
Learn more about Seastar on the main project website.