Project Structure
Although the project structure can be arbitrary, it looks reasonable to provide some advices here:
- Use a separate crate for every actor group.
- It speeds up a build time.
- It helps to isolate code.
- Use separate crates for protocols, where messages are defined. Internal messages (timer ticks, inner group messages etc) are defined inside a group's crate.
- Actor crates shouldn't depend on each other. Instead, they should depend on protocol crates.
- It helps to achieve loosely coupling.
- Prefer integration tests (
tests/
) over unit tests (mod tests
). Unit tests are still fine for internal structures.- Integration tests use no implementation details and relies only on protocols.
- Store libraries (additional code potentially used by multiple actors) separately from actors' code. It's ok to depends on protocols in that code, but don't depend on actors.
libs/
in the example below. - Store different parts of a group in dedicated files, it siplifies navigation:
exec()
and message handling inactor.rs
.- An inner-group router in
router.rs
. - A group's config in
config.rs
.
- Store topology definitions separately from actors' code. Services can share actors. Also, it's a good place for additional files like systemd units and so on.
services/
in the example below.
For instance:
actors/
<actor_name_1>/
src/
mod.rs
actor.rs
config.rs
router.rs
tests/
helpers.rs
test_<name_1>.rs
test_<name_2>.rs
Cargo.toml
<actor_name_2>/
protocol/
src/
lib.rs
Cargo.toml
libs/
<lib_name_1>/
<lib_name_2>/
services/
<service_name_1>/
<service_name_2>/
Cargo.toml
Cargo.lock
rustfmt.toml