内容简介:Actix is a Rust actors framework.To useIn order to use actix you first need to create a
Actix
Actix is a Rust actors framework.
- User Guide
- API Documentation (Development)
- API Documentation (Releases)
- Cargo package: actix
- Minimum supported Rust version: 1.39 or later
Platform | Build Status |
---|---|
Linux | |
macOS | |
Windows |
Features
- Async/Sync actors.
- Actor communication in a local/thread context.
- Uses Futures for asynchronous message handling.
- HTTP1/HTTP2 support ( actix-web )
- Actor supervision.
- Typed messages (No
Any
type).
Usage
To use actix
, add this to your Cargo.toml
:
[dependencies] actix = "0.9"
Initialize Actix
In order to use actix you first need to create a System
.
fn main() { let system = actix::System::new("test"); system.run(); }
Actix uses the tokio event loop. System::new()
creates a new event loop and starts the System
actor. system.run()
starts the tokio event loop, and will finish once the System
actor receives the SystemExit
message.
Let's create a simple Actor.
Implement an Actor
In order to define an actor you need to define a struct and have it implement the Actor
trait.
use actix::{Actor, Addr, Arbiter, Context, System}; struct MyActor; impl Actor for MyActor { type Context = Context<Self>; fn started(&mut self, ctx: &mut Self::Context) { println!("I am alive!"); System::current().stop(); // <- stop system } } fn main() { let system = System::new("test"); let addr = MyActor.start(); system.run(); }
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 docs. You can implement started
, stopping
and stopped
methods of the Actor trait. started
gets called when actor starts and stopping
when actor finishes. Check API documentation for more information on the 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.
use futures::{future, Future}; use actix::*; // this is our Message struct Sum(usize, usize); // we have to define the response type for `Sum` message impl Message for Sum { type Result = usize; } // Actor definition struct Summator; impl Actor for Summator { type Context = Context<Self>; } // now we need to define `MessageHandler` for the `Sum` message. impl Handler<Sum> for Summator { type Result = usize; // <- Message response type fn handle(&mut self, msg: Sum, ctx: &mut Context<Self>) -> Self::Result { msg.0 + msg.1 } } fn main() { let sys = System::new("test"); let addr = Summator.start(); let res = addr.send(Sum(10, 5)); // <- send message and get future for result Arbiter::spawn(res.then(|res| { match res { Ok(result) => println!("SUM: {}", result), _ => println!("Something wrong"), } System::current().stop(); future::result(Ok(())) })); sys.run(); }
All communications with actors go through an Addr
object. You can do_send
a message without waiting for a response, or send
an actor with specific message. The Message
trait defines the result type for a message.
Actor state and subscription for specific messages
You may have noticed that methods of 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
.
use std::time::Duration; use actix::prelude::*; #[derive(Message)] struct Ping { pub id: usize } // Actor definition struct Game { counter: usize, addr: Recipient<Ping>, } impl Actor for Game { type Context = Context<Game>; } // simple message handler for Ping message impl Handler<Ping> for Game { type Result = (); fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) { self.counter += 1; if self.counter > 10 { System::current().stop(); } else { println!("Ping received {:?}", msg.id); // wait 100 nanos ctx.run_later(Duration::new(0, 100), move |act, _| { act.addr.do_send(Ping{id: msg.id + 1}); }); } } } fn main() { let system = System::new("test"); // To get a Recipient object, we need to use a different builder method // which will allow postponing actor creation let addr = 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, addr: addr.recipient()}.start(); // let's start pings addr2.do_send(Ping{id: 10}); // now we can finally create first actor Game{counter: 0, addr: addr2.recipient()} }); system.run(); }
chat example
There is a chat example which provides a basic example of networking client/server service.
fectl
You may consider checking out fectl utility. It is written with actix
and shows how to create networking application with relatively complex interactions.
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 or http://www.apache.org/licenses/LICENSE-2.0 )
- MIT license ( LICENSE-MIT or http://opensource.org/licenses/MIT )
at your option.
Code of Conduct
Contribution to the actix crate is organized under the terms of the Contributor Covenant, the maintainer of actix, @fafhrd91, promises to intervene to uphold that code of conduct.
以上所述就是小编给大家介绍的《Actix: Actor Framework for Rust》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机组成与设计硬件/软件接口
[美] David A.Patterson、John L.Hennessy / 郑纬民 / 机械工业出版社 / 2007-4 / 75.00元
《计算机组成与设计硬件:软件接口》(原书第3版)是计算机组成的经典教材。全书着眼于当前计算机设计中最基本的概念,展示了软硬件间的关系,并全面介绍当代计算机系统发展的主流技术和最新成就。同以往版本一样,《计算机组成与设计硬件:软件接口》(原书第3版)采用MIPS处理器作为展示计算机硬件技术基本功能的核心。书中逐条指令地列举了完整的MIPS指令集,并介绍了网络和多处理器结构的基本内容。将CPU性能和程......一起来看看 《计算机组成与设计硬件/软件接口》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
JSON 在线解析
在线 JSON 格式化工具