All Projects → actix → Actix

actix / Actix

Licence: other
Actor framework for Rust.

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Actix

Bastion
Highly-available Distributed Fault-tolerant Runtime
Stars: ✭ 2,333 (-65.51%)
Mutual labels:  hacktoberfest, concurrency, actor
Akka
Build highly concurrent, distributed, and resilient message-driven applications on the JVM
Stars: ✭ 11,938 (+76.49%)
Mutual labels:  hacktoberfest, concurrency, actor-model
Akka.net
Port of Akka actors for .NET
Stars: ✭ 4,024 (-40.51%)
Mutual labels:  concurrency, actor-model, actor
Sobjectizer
An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.
Stars: ✭ 172 (-97.46%)
Mutual labels:  concurrency, actor-model, actor
rockgo
A developing game server framework,based on Entity Component System(ECS).
Stars: ✭ 617 (-90.88%)
Mutual labels:  actor-model, concurrency
Actors.jl
Concurrent computing in Julia based on the Actor Model
Stars: ✭ 95 (-98.6%)
Mutual labels:  actor-model, concurrency
cl-gserver
Actor framework featuring actors and agents for easy access to state and asynchronous operations.
Stars: ✭ 121 (-98.21%)
Mutual labels:  concurrency, actor
dogactor
Distributed Systems,Based on Actor Model
Stars: ✭ 70 (-98.97%)
Mutual labels:  actor-model, actor
theater
Actor framework for Dart. This package makes it easier to work with isolates, create clusters of isolates.
Stars: ✭ 29 (-99.57%)
Mutual labels:  actor-model, concurrency
transit
Massively real-time city transit streaming application
Stars: ✭ 20 (-99.7%)
Mutual labels:  actor-model, concurrency
Ava
Node.js test runner that lets you develop with confidence 🚀
Stars: ✭ 19,458 (+187.67%)
Mutual labels:  hacktoberfest, concurrency
actors
Actor Model library for Dart.
Stars: ✭ 40 (-99.41%)
Mutual labels:  actor-model, concurrency
Joshuto
ranger-like terminal file manager written in Rust
Stars: ✭ 224 (-96.69%)
Mutual labels:  hacktoberfest, concurrency
ComposableAsync
Create, compose and inject asynchronous behaviors in .Net Framework and .Net Core.
Stars: ✭ 28 (-99.59%)
Mutual labels:  actor-model, concurrency
Cloudi
A Cloud at the lowest level!
Stars: ✭ 352 (-94.8%)
Mutual labels:  concurrency, actor-model
Qpc
QP/C real-time embedded framework/RTOS for embedded systems based on active objects (actors) and hierarchical state machines
Stars: ✭ 379 (-94.4%)
Mutual labels:  actor-model, actor
traffic
Massively real-time traffic streaming application
Stars: ✭ 25 (-99.63%)
Mutual labels:  actor-model, concurrency
Thespian
Python Actor concurrency library
Stars: ✭ 220 (-96.75%)
Mutual labels:  concurrency, actor-model
Promise Pool
Map-like, concurrent promise processing
Stars: ✭ 258 (-96.19%)
Mutual labels:  hacktoberfest, concurrency
Coobjc
coobjc provides coroutine support for Objective-C and Swift. We added await method、generator and actor model like C#、Javascript and Kotlin. For convenience, we added coroutine categories for some Foundation and UIKit API in cokit framework like NSFileManager, JSON, NSData, UIImage etc. We also add tuple support in coobjc.
Stars: ✭ 3,921 (-42.03%)
Mutual labels:  actor-model, actor

Actix

Actor framework for Rust

crates.io Documentation Version License Dependency Status
build status codecov Downloads Chat on Discord

Documentation

Features

  • Async and sync actors
  • Actor communication in a local/thread context
  • Uses futures for asynchronous message handling
  • Actor supervision
  • Typed messages (No Any type)
  • Runs on stable Rust 1.46+

Usage

To use actix, add this to your Cargo.toml:

[dependencies]
actix = "0.12"

Initialize Actix

In order to use actix you first need to create a System.

fn main() {
    let system = actix::System::new();

    system.run();
}

Actix uses the 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 trait.

use actix::{Actor, Addr, 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 mut system = System::new();

    let addr = system.block_on(async { 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 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.

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.

use actix::prelude::*;

// this is our Message
// we have to define the response type (rtype)
#[derive(Message)]
#[rtype(result = "usize")]
struct Sum(usize, usize);

// Actor definition
struct Calculator;

impl Actor for Calculator {
    type Context = Context<Self>;
}

// now we need to implement `Handler` on `Calculator` for the `Sum` message.
impl Handler<Sum> for Calculator {
    type Result = usize; // <- Message response type

    fn handle(&mut self, msg: Sum, ctx: &mut Context<Self>) -> 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 result

    match 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.

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<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!("[{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 mut system = System::new();

    // To get a Recipient object, we need to use a different builder method
    // which will allow postponing actor creation
    let addr = system.block_on(async {
        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(),
            }
        });
    });

    system.run();
}

Chat Example

See this chat example which shows more comprehensive usage in a networking client/server service.

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

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].