Git Product home page Git Product logo

actix-redis's Introduction

Actix

Actor framework for Rust

crates.io Documentation Minimum Supported Rust Version License Dependency Status
CI 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.68+

Usage

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

[dependencies]
actix = "0.13"

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, 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();

    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.

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

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.

actix-redis's People

Contributors

ava57r avatar dowwie avatar fafhrd91 avatar johntitor avatar pandaman64 avatar ryanmcgrath avatar turbo87 avatar yinyanlv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

actix-redis's Issues

Supporting transactions: appropriate?

redis_async leaves redis transactions as an open question.

I think this crate would be more well suited to handle transactions than redis_async since we have helpers like AsyncContext::wait which could delay all requests on a channel until a transaction is fully complete.

Do you think that that would be within the scope of this repository? If support for transactions were PRd, would it be accepted?

support for actix_web 1.0.2

hiii,

please resolved depedency library for actix web v 1.0.2

this is log error fro cargo build

failed to select a version for ring.
... required by package actix-http v0.2.4
... which is depended on by actix-web v1.0.2
... which is depended on by payslip v0.1.0 (/Users/maulana/rust/payslip)
versions that meet the requirements ^0.14.6 are: 0.14.6

the package ring links to the native library ring-asm, but it conflicts with a previous package which links to ring-asm as well:
package ring v0.13.5
... which is depended on by cookie v0.11.0
... which is depended on by actix-redis v0.5.1
... which is depended on by payslip v0.1.0 (/Users/maulana/rust/payslip)

thanks brother,

Reconnect to redis

RedisActor needs to be able to reconnect to redis server. This requires changes in actix

error

i have alway error in another projet

git clone https://github.com/ami44/tmp-actix-web-redis.git + cargo run display

 --> src/main.rs:40:25
   |
40 |             .middleware(middleware::SessionStorage::new(
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `actix_web::middleware::SessionBackend<_>` is not implemented for `actix_redis::RedisSessionBackend`
   |
   = note: required by `<actix_web::middleware::SessionStorage<T, S>>::new`

error[E0277]: the trait bound `actix_redis::RedisSessionBackend: actix_web::middleware::SessionBackend<()>` is not satisfied
  --> src/main.rs:40:14
   |
40 |             .middleware(middleware::SessionStorage::new(
   |              ^^^^^^^^^^ the trait `actix_web::middleware::SessionBackend<()>` is not implemented for `actix_redis::RedisSessionBackend`
   |
   = note: required because of the requirements on the impl of `actix_web::middleware::Middleware<()>` for `actix_web::middleware::SessionStorage<actix_redis::RedisSessionBackend, ()>`

failed to build with version 0.6.0

It depends on actix_utils and when I try to build it.
use actix_utils::cloneable::CloneableService;.and could not find cloneable in actix_utils.It seems that you had removed it from actix_utils

Docs say the users can see the session content but they can only see session key

The documentation of RedisSessionBackend says: whatever you write into your session is visible by the user (but not modifiable). The user only sees the session key and not the content as far as I can tell. Is this an error in the documentation or am I reading it wrong?

Here is the line in question:

/// Note that whatever you write into your session is visible by the user (but

copy/paste error

I have copy/paste example code examples/basic.rs + git pull actix + actix-web + actix-redis

and i have

error[E0277]: the trait bound `actix_redis::RedisSessionBackend: actix_web::middleware::SessionBackend<_>` is not satisfied
  --> src/main.rs:40:25
   |
40 |             .middleware(middleware::SessionStorage::new(
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `actix_web::middleware::SessionBackend<_>` is not implemented for `actix_redis::RedisSessionBackend`
   |
   = note: required by `<actix_web::middleware::SessionStorage<T, S>>::new`

error[E0277]: the trait bound `actix_redis::RedisSessionBackend: actix_web::middleware::SessionBackend<()>` is not satisfied
  --> src/main.rs:40:14
   |
40 |             .middleware(middleware::SessionStorage::new(
   |              ^^^^^^^^^^ the trait `actix_web::middleware::SessionBackend<()>` is not implemented for `actix_redis::RedisSessionBackend`
   |
   = note: required because of the requirements on the impl of `actix_web::middleware::Middleware<()>` for `actix_web::middleware::SessionStorage<actix_redis::RedisSessionBackend, ()>`

error: aborting due to 2 previous errors

Conflicts with `actix-web v1.0.0-beta.1`

actix-redis v0.5.1 conflicts with actix-web v1.0.0-beta.1.

The log is here:
error: failed to select a version for `ring`.
    ... required by package `actix-http v0.1.1`
    ... which is depended on by `actix-web v1.0.0-beta.1`
    ... which is depended on by `foo v0.1.0`
versions that meet the requirements `^0.14.6` are: 0.14.6

the package `ring` links to the native library `ring-asm`, but it conflicts with a previous package which links to `ring-asm` as well:
package `ring v0.13.5`
    ... which is depended on by `cookie v0.11.0`
    ... which is depended on by `actix-redis v0.5.1`
    ... which is depended on by `foo v0.1.0`

But it seems that master branch fixes this, so could I know when next release comes?

Connect to password protected redis

Maybe it is just me, but I can not find a place to config password for Redis backend in actix-redis, so I guess I will have to manually send AUTH password every time?

Thanks.

Not recieving any cookie on client side

Hey, I am trying to use this crate to implement a cookie based auth system in my actix web server. However, using the example in the README, I am not recieving any cookie headers on the client side. Is it the intended behaviour or am i missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.