Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/actix/actix
Actor framework for Rust.
https://github.com/actix/actix
actix actor actor-model concurrency hacktoberfest rust
Last synced: 7 days ago
JSON representation
Actor framework for Rust.
- Host: GitHub
- URL: https://github.com/actix/actix
- Owner: actix
- License: apache-2.0
- Created: 2017-09-18T05:13:28.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-10-07T04:40:07.000Z (3 months ago)
- Last Synced: 2024-10-29T16:58:53.185Z (2 months ago)
- Topics: actix, actor, actor-model, concurrency, hacktoberfest, rust
- Language: Rust
- Homepage:
- Size: 16.1 MB
- Stars: 8,632
- Watchers: 141
- Forks: 651
- Open Issues: 35
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- awesome-rust-cn - actix/actix - ci.org/actix/actix.svg?branch=master">](https://travis-ci.org/actix/actix) (Libraries / Network programming)
- awesome-rust - actix/actix - ci.org/actix/actix.svg?branch=master">](https://travis-ci.org/actix/actix) (Libraries / Network programming)
- awesome-ccamel - actix/actix - Actor framework for Rust. (Rust)
- awesome-actor - Actix - Actor framework for Rust (Frameworks, Libraries and Tools / Application Frameworks)
- programming-awesome-list - actix/actix
- awesome-rust - actix/actix
- awesome-rust-cn - actix/actix
- awesome-list - actix
- awesome-code-for-gamedev - actix/actix - Actor framework for Rust (Objects - Entity, Actor / UI Test Automation Scripting)
- awesome-rust-zh - actix/actix - Rust 的 Actor 库[<img src="https://api.travis-ci.org/actix/actix.svg?branch=master">](https://travis-ci.org/actix/actix) (库 / 网络编程)
- StarryDivineSky - actix/actix
- my-awesome - actix/actix - model,concurrency,hacktoberfest,rust pushed_at:2024-12 star:8.7k fork:0.7k Actor framework for Rust. (Rust)
- awesome-starred - actix/actix - Actor framework for Rust. (hacktoberfest)
README
Actix
Actor framework for Rust
[![crates.io](https://img.shields.io/crates/v/actix?label=latest)](https://crates.io/crates/actix)
[![Documentation](https://docs.rs/actix/badge.svg?version=0.13.5)](https://docs.rs/actix/0.13.5)
![Minimum Supported Rust Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg)
![License](https://img.shields.io/crates/l/actix.svg)
[![Dependency Status](https://deps.rs/crate/actix/0.13.5/status.svg)](https://deps.rs/crate/actix/0.13.5)
[![CI](https://github.com/actix/actix/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/actix/actix/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix)
![Downloads](https://img.shields.io/crates/d/actix.svg)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/GMuKN5b8aR)
## Documentation
- [User Guide](https://actix.rs/docs/actix)
- [API Documentation](https://docs.rs/actix)## Features
- Async and sync actors
- Actor communication in a local/thread context
- Uses [futures](https://crates.io/crates/futures) for asynchronous message handling
- Actor supervision
- Typed messages (No `Any` type)
- Runs on stable Rust 1.68+## Usage
To use `actix`, add this to your `Cargo.toml`:
```toml
[dependencies]
actix = "0.13"
```### Initialize Actix
In order to use actix you first need to create a `System`.
```rust,ignore
fn main() {
let system = actix::System::new();system.run();
}
```Actix uses the [Tokio](https://github.com/tokio-rs/tokio) runtime. `System::new()` creates a new event loop. `System.run()` starts the Tokio event loop, and will finish once the `System` actor receives the `SystemExit` message.
### Implementing an Actor
In order to define an actor you need to define a struct and have it implement the [`Actor`](https://docs.rs/actix/latest/actix/trait.Actor.html) trait.
```rust
use actix::{Actor, Context, System};struct MyActor;
impl Actor for MyActor {
type Context = Context;fn started(&mut self, _ctx: &mut Self::Context) {
println!("I am alive!");
System::current().stop(); // <- stop system
}
}fn main() {
let system = System::new();let _addr = system.block_on(async { MyActor.start() });
system.run().unwrap();
}
```Spawning a new actor is achieved via the `start` and `create` methods of the [Actor trait]. It provides several different ways of creating actors; for details, check the docs. You can implement the `started`, `stopping` and `stopped` methods of the Actor trait. `started` gets called when the actor starts and `stopping` when the actor finishes. Check the API docs for more information on [the actor lifecycle].
[Actor trait]: https://docs.rs/actix/latest/actix/trait.Actor.html
[the actor lifecycle]: https://actix.rs/docs/actix/actor#actor-lifecycle### Handle Messages
An Actor communicates with another Actor by sending messages. In actix all messages are typed. Let's define a simple `Sum` message with two `usize` parameters and an actor which will accept this message and return the sum of those two numbers. Here we use the `#[actix::main]` attribute as an easier way to start our `System` and drive our main function so we can easily `.await` for the responses sent back from the `Actor`.
```rust
use actix::prelude::*;// this is our Message
// we have to define the response type (rtype)
#[derive(Message)]
#[rtype(usize)]
struct Sum(usize, usize);// Actor definition
struct Calculator;impl Actor for Calculator {
type Context = Context;
}// now we need to implement `Handler` on `Calculator` for the `Sum` message.
impl Handler for Calculator {
type Result = usize; // <- Message response typefn handle(&mut self, msg: Sum, _ctx: &mut Context) -> Self::Result {
msg.0 + msg.1
}
}#[actix::main] // <- starts the system and block until future resolves
async fn main() {
let addr = Calculator.start();
let res = addr.send(Sum(10, 5)).await; // <- send message and get future for resultmatch res {
Ok(result) => println!("SUM: {}", result),
_ => println!("Communication to the actor has failed"),
}
}
```All communications with actors go through an `Addr` object. You can `do_send` a message without waiting for a response, or you can `send` an actor a specific message. The `Message` trait defines the result type for a message.
### Actor State And Subscription For Specific Messages
You may have noticed that the methods of the `Actor` and `Handler` traits accept `&mut self`, so you are welcome to store anything in an actor and mutate it whenever necessary.
Address objects require an actor type, but if we just want to send a specific message to an actor that can handle the message, we can use the `Recipient` interface. Let's create a new actor that uses `Recipient`.
```rust
use actix::prelude::*;
use std::time::Duration;#[derive(Message)]
#[rtype(result = "()")]
struct Ping {
pub id: usize,
}// Actor definition
struct Game {
counter: usize,
name: String,
recipient: Recipient,
}impl Actor for Game {
type Context = Context;
}// simple message handler for Ping message
impl Handler for Game {
type Result = ();fn handle(&mut self, msg: Ping, ctx: &mut Context) {
self.counter += 1;if self.counter > 10 {
System::current().stop();
} else {
println!("[{0}] Ping received {1}", self.name, msg.id);// wait 100 nanoseconds
ctx.run_later(Duration::new(0, 100), move |act, _| {
act.recipient.do_send(Ping { id: msg.id + 1 });
});
}
}
}fn main() {
let system = System::new();system.block_on(async {
// To create a cyclic game link, we need to use a different constructor
// method to get access to its recipient before it starts.
let _game = Game::create(|ctx| {
// now we can get an address of the first actor and create the second actor
let addr = ctx.address();let addr2 = Game {
counter: 0,
name: String::from("Game 2"),
recipient: addr.recipient(),
}
.start();// let's start pings
addr2.do_send(Ping { id: 10 });// now we can finally create first actor
Game {
counter: 0,
name: String::from("Game 1"),
recipient: addr2.recipient(),
}
});
});// let the actors all run until they've shut themselves down
system.run().unwrap();
}
```### Chat Example
See this [chat example] which shows more comprehensive usage in a networking client/server service.
[chat example]: https://github.com/actix/examples/tree/HEAD/websockets/chat-tcp
## Contributing
All contributions are welcome, if you have a feature request don't hesitate to open an issue!
## License
This project is licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)at your option.
## Code of Conduct
Contribution to the actix repo is organized under the terms of the Contributor Covenant. The Actix team promises to intervene to uphold that code of conduct.