Herdr UI
Herdr의 TUI가 뛰어나며, 창을 통해 추가되는 기능
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.