12 ms·
Actix – Actor Framework for Rust
- smallstepforman 7y agoActors in principle (isolated objects assigned to threads) sound great until you need to SHARE data, then you enter a new universe of compromises where you need locking mechanisms (for performance), but no language semantics support it natively. Pony introduced reference capabilities but that still created a cludge for those times you needed synchronous access. There is no model yet where locking primitives are associated with resource handles.
- shanxS 7y ago> ... sound great until you need to SHARE data ... If by "share" you mean one writer and others with read-only access, then staleness of data is a question. In java we have volatile for that, I think there is a similar keyword in C++. However, you'll have to maintain the invariant of "one writer and others with read-only access". If you don't need absolute latest version, you can do message passing/pubsub etc. If by "share" you mean multiple writers, I'll have to question your design decision. Why do multiple threads have to write to same memory location? Most of the time, you can get away with partitioning/sharding. If you disagree, I'd like to know why?
- smallstepforman 7y agoUnfortunately, our objects are not isolated, they interact with the world, and often need to be shared when we cannot copy the resource (performance). Eg. a (partitioned) rendering surface may be written simultaneously, a physics engine needs to know what objects are in the game world, multiple bank accounts need to be updated simultaneously, etc. By design is not always possible to sequence, some transactions must be atomic across multiple objects.
- ahasani 7y agoYes they are, atom is in isolation, cell has membrane, we have a body we have isolation and encapsulation in physics/chemistry/biology. In actor model message passing is interaction. Since you mentioned game, check out https://github.com/aeplay/kay https://github.com/aeplay/kay, which is the isolation "objects" for https://github.com/citybound/citybound https://github.com/citybound/citybound "physics engine". On multiple bank accounts, well an account is an actor, so there is no problem there, please have a look at http://proto.actor/blog/2017/06/24/money-transfer-saga.html http://proto.actor/blog/2017/06/24/money-transfer-saga.html
- brentjanderson 7y agoErlang OTP 21.2 introduced the idea of `persistent_term`, which is a data structure any process can read from at the expense of being costly to modify. This provides a nice alternative to locks, since you can have a single actor/process responsible for handling writes (and deciding when to flush those writes, triggering a GC pause on processes depending on the term) but any number of actors reading from that persistent term at full-speed.
- jamil7 7y agoWhats the state of Rust if I wanted to get into it for backend development? I've looked briefly into Rocket and liked it but didn't delve too deep, I understand Actix is one of the most mature?
- hd4 7y agohttps://www.arewewebyet.org/ https://www.arewewebyet.org/
- _-___________-_ 7y agoI wouldn't call Actix the most mature, but it's definitely the one that gets talked about the most. I built a fairly complex backend directly on top of Hyper[0] (it doesn't even involve that much glue, really) in 2016 and have updated it as Rust and Hyper have matured. It's actually a delight to work on, and I brought a new hire on board recently who had no trouble getting up to speed, since everything is just straightforward, idiomatic Rust. I've looked at basically every Rust "web framework" that's been released since 2016, and I can't see any of them simplifying the codebase enough to justify using them. Quite a few of these frameworks result in code that isn't obvious to a Rust programmer who hasn't used that framework before, too, which I consider a disadvantage (I prefer obvious over clever). [0] edited to add for those that may not be aware: Hyper is a client & server HTTP library. Many/most of the frameworks are built on top of it.
- DarthGhandi 7y agoActix smashes a lot of benchmarks. For the regular dev/company in production use have no idea why people would use it. Hyper seems the sane option for most trying to simply build a backend. It's really good to see others building on it though. Won't deny how clunky it once was before async got stabilized.
- _-___________-_ 7y agoYou have to adjust the filters, because hyper isn't considered a "framework", but the TechEmpower benchmarks show hyper beating even actix (though it's narrow). Definitely agree things were pretty clunky for async Rust web stuff before async/await!
- ncmncm 7y agoCan somebody please summarize the outcome of the recent kerfuffle? I don't mind which way it came out, but it seems worth knowing what it was. I absolutely don't want any even-slightly-inflammatory answer.
- milgrim 7y agoThe project has a new leader now: https://github.com/actix/actix-web/issues/1289 https://github.com/actix/actix-web/issues/1289
- _-___________-_ 7y agoThis is from memory, I would welcome any corrections. Actix was written with a lot of unsafe code[0], which some people considered unnecessary and potentially dangerous in a web framework. In some cases the unsafe code may have been performing better than equivalent safe code. In other cases, it was possible to rewrite with safe code without losing performance. People submitted patches to replace unsafe code with safe code. The maintainer of Actix responded with hostility to some of these patches, and (at least for some of the patches) did not seem to see the reason why people wanted these changes. Subsequently, a lot of hostility was directed at the maintainer on various public Internet fora. Ultimately, the maintainer of Actix deleted the repository from GitHub, but then had a change of heart and restored it, with a new maintainer. [0] unsafe code according to the Rust definition of unsafe: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
- Dowwie 7y agoYour description is accurate and fair
- undecisive 7y agoThat seems a pretty balanced summary from my understanding of it. One thing that I think should be noted: a lot has been said about this framing the original developer as unwilling. I'd say an unfair amount - from what I've seen, "cautiousness" would be a better description of his attitude, and hostility seems to have been shown when people blindly wade in ignoring all the discussion. So for example, back in 2018, here he is publicly mulling it over: https://github.com/actix/actix-web/issues/289#issuecomment-395800266 https://github.com/actix/actix-web/issues/289#issuecomment-3... and https://github.com/actix/actix-web/issues/289#issuecomment-397827214 https://github.com/actix/actix-web/issues/289#issuecomment-3... Here he is actively working to reduce the reliance on unsafe practices: https://github.com/actix/actix-web/issues/289#issuecomment-397840016 https://github.com/actix/actix-web/issues/289#issuecomment-3... Here he actively and very concisely points out his actual viewpoint: https://github.com/actix/actix-web/issues/289#issuecomment-398739160 https://github.com/actix/actix-web/issues/289#issuecomment-3... ... and there are plenty of other examples in this and other tickets. Massive actions were taken by others and himself to significantly reduce the unsafe code where possible, and yet it seems the abuse kept coming. I'd be interested to hear whether the new maintainer has had similar experiences. Unfortunately, our preferences in software development, often a product of a desire to generalise a specific overreaction, tend to become quasi-religious and puritanical. Members get outcast from their communities for trying to speak sense. I hope that this debacle will cause the community to mature, though I fear many will see it as a win and galvanise their viewpoint. We must remember that silver bullets can kill more than just werewolves.
- shawnz 7y agoWhat is the difference between the actor model and object oriented programming? It seems to me like they are basically the same paradigm but with all the names changed, and some additional restrictions like all messages being async and objects only being able to process one message at a time. Why is it necessary to create a whole new paradigm just to enforce such a style?
- vbezhenar 7y agoYou can run every actor in a separate thread or even in a separate machine, making the whole system highly scalable. Whether you'll consider that a new paradigm or not, is question of definitions.
- shawnz 7y agoIsn't that basically the same as remote method invocation in OO systems?
- nicoburns 7y agoIt depends what you mean by OO. The Actor system is basically Smalltalk-style OO. Which is very different to Java-style OO, or JavaScript-style OO. Most people who talk about OO, are talking about the Java style.
- bsaul 7y agoThe way i see it : Object is the association of some functions with a state Actor is the association of object with an execution thread. So, actor = bounded (functions , state , thread) (thread in the sense of execution thread, not necesseraly an OS thread). With this definition, actors can't "share" a thread, and so need to communicate through asynchronous message passing / function invocation.
- imtringued 7y agoAlthough I'm not sure what you really mean by "remote method invocation", the idea of remote method invocation in OO systems should be impossible or incredibly difficult considering the semantics of a method call. Method calls are synchronous and they are not allowed to fail under any circumstance. But in the context of distributed systems you have to choose between at most once or at least once delivery which are semantically incompatible with OOP style method calls. Your methods will have to be written with the expectation that they are called multiple times or maybe not at all and most OOP code doesn't satisfy these expectations because the OOP model doesn't require it. If you extend the OOP model with message semantics of the actor model then what you get is not just OOP+messaging. It's the actor model. Also you may have misunderstood something very fundamental. The benefit of paradigms isn't to be completely different. It's that everyone that shares a paradigm follows the same design philosophy. Imagine a mixed code base consisting of traditional OOP (with locks), actor model, async/await, promises. It would be very difficult to understand and sometimes it isn't obvious which of these is used. Some functions are asynchronous or they may fail but you may not know that because every single line could do a different thing. They may even be incompatible with each other. If you follow a single paradigm instead of many different ones you can avoid a lot of confusion and wasted work.
- dragonsh 7y agoThis framework's core developer has left, probably new community took it over. Hopefully it will continue to be supported and developed. Rust still has a way to go for being a mature eco-system for doing any serious web programming work. Given the focus of Rust on systems programming, I will still be careful to consider it for anything web related. Hopefully situations like abandoning a project suddenly will not happen again. [1] [2] [1] https://words.steveklabnik.com/a-sad-day-for-rust https://words.steveklabnik.com/a-sad-day-for-rust [2] https://github.com/actix/actix-web/issues/1289 https://github.com/actix/actix-web/issues/1289
- zelly 7y agoWhen you adopt a dependency, you should be prepared to maintain it yourself if no one else does. There's a reason open source licenses say "no warranty" in all-caps. Sadly this seems to be lost on the npm and npm-adjacent crowd, who installs gigs of random people's personal projects for breakfast.
- Qwuke 7y agoJust an anecdote, but I've used Rust for a handful of production web services for a couple of years now. The ecosystem is immature relative to Java or Ruby, but I've quickly built maintainable and performant services without feeling like there was missing tooling. With many (most?) Rust web frameworks now supporting async, I'd feel a lot more comfortable recommending it for 'serious' web programming work to teams interested in learning Rust.
- Dowwie 7y agoYou seem to have a superficial level understanding about the Rust ecosystem for web development and for the actix ecosystem. Yet, this hasn't stopped others from trusting your opinion or agreeing with your comment, unfortunately. This post is for the original actor architecture. The next architecture, which should have never been called actix, was based on a completely different architecture. This second version prevailed and remains in use today, as actix-net. Actix-web v2 uses actix-net. It features async-await syntax, is feature complete, and the architecture is mature. The project includes a guide, api docs, a vast collection of examples, and growing ecosystem. Actix-net is very high-performance. The main concern about any actix project was related to poorly communicating uses of unsafe code, refusing to codify a policy about unsafe, and working with others, respectfully, to address real undefined behaviors. The author has retired from the projects, for now. Others have stepped up to maintain and improve. It's very exciting to see people addressing unsafe blocks. Most importantly, actix-web lives on! The expectations and treatment of authors who spend hundreds of hours on bleeding edge, open source work is also a major problem. This problem isn't specific to Rust, either.
- dmm 7y agoThe naming is a little confusing here. This is Actix the actor model library, not "Actix web" the web framework that's usually discussed. Originally "Actix web" depended on Actix the actor library, but no longer. Though they can be used together. And I think websockets still require actors? I'm using both Actix and Actix web for a personal project. I like it a lot and think the actor model is good fit for applications that don't fit well into a request lifecycle. My main pain point with it is the use of futures. Right now it's a huge pain to have more than one return value in an Actor Handler, the functions that handle actor messages. Even if you box the returned Future, you end up having to use futures::Either a bunch and when you mess it up you get tons of confusing errors filled with the huge inferred types. Implementing something like: if (condition1) { return <future for service call1>; } else if (condition2) { return <future for service call2>; } else { return <no-op future>; } Is a big pain requiring two layers of future::Either. Or I just don't know what I'm doing, which is very possible. async/await would be a huge improvement, but can't be used at the moment, even though the current version of Actix uses std::future's.
- aphexairlines 7y agoCan't you use async/await with the compat libraries for futures and for tokio? https://tokio.rs/blog/2019-12-compat/ https://tokio.rs/blog/2019-12-compat/
- kevinmgranger 7y ago> Even if you box the returned Future, you end up having to use futures::Either a bunch That's really strange. A Boxed future is the end-all-be-all of not caring about the underlying type. Would you mind sharing a snippet of code that shows where you need both a Boxed future and Either?
- dmm 7y agoYou're probably right, I must be missing something. I'm also still on futures 0.1 because I'm still porting it to std::futures. Here's an example of what I was discussing: https://github.com/dmm/exopticon/blob/c40d14c80c150ef62707320085b8f9243160c8a8/exopticon/src/camera_routes.rs#L245 https://github.com/dmm/exopticon/blob/c40d14c80c150ef6270732... The idea is that I want to implement a relative ptz move on a camera but some cameras have a broken relative move implementation so in that case we instead use a continuous move + a delay + a continuous stop. The final case is when a camera has no ptz it returns Http::NotFound.
- andrewzah 7y agoActix (the actor framework) is separate from what people are discussing here: actix-web, which supports actix). In earlier versions of actix-web it was based around actix; I remember implementing actors and handlers. Since 1.0 or so that got changed to more of a standard setup. I’ll add my 2c on actix-web: in my opinion it tries to do too much. hyper (simply based on tokio) is all you need for a fast async server. Anecdotally, I know many people who basically use just this stack, over actix-web/warp/tower etc. There are other actor systems, like kay [0]. [0]: https://citybound.github.io/citybound/kay/index.html https://citybound.github.io/citybound/kay/index.html
- walkingolof 7y agoHow does it stack up against more mature actor frameworks like Akka? (akka.io)
- ryuukk_ 7y agowhat a ugly syntax rust has, omg
- xedrac 7y agoI'm currently in the process of removing actix from one of my projects and replacing it with asyc/await and some channels. Actix comes with a ton of dependencies and doesn't buy you a whole lot anymore.
- polskibus 7y agoOut of curiosity - actix seems to be very performant compared to actor frameworks implemented in other languages - would it be a good fit to implement a database using it? For example mapping worker pool and workers to actors?
- rofrol 7y agoI would rather use linux io_uring https://www.reddit.com/r/rust/comments/f06y7m/comment/fguw9a3 https://www.reddit.com/r/rust/comments/f06y7m/comment/fguw9a...
- 3fe9a03ccd14ca5 7y agoI’m really excited about this project. Using Akka was one of those things that made distributed/parallel execution just “click”. Particularly useful was being able to draw your architecture the same way one might draw an organization on a whiteboard. Everyone can quickly understand what happens and who is responsible for what.
- habitue 7y agoHighly recommend Bastion if you're looking for a Rust Actor library / runtime. It uses async/await etc, and has supervision trees and restart strategies taken straight from Erlang/OTP https://docs.rs/bastion/0.3.4/bastion/ https://docs.rs/bastion/0.3.4/bastion/ https://github.com/bastion-rs/bastion https://github.com/bastion-rs/bastion
- captain_crabs 7y agowould you even suggest this over riker?
- habitue 7y agoI haven't used Riker, is it good?
- dantodor 7y agoI'm amazed on how much discussion digressed to actix-web. Understandable, seen the latest happenings there, but still... I tried quite a while ago Actix, coming from Erlang/Elixir and Scala/Akka. While the cognitive load of using it was not high, when I started my first test, I noticed one core being maxed out, and all others sleeping, which was kinda unusual for me. I asked why, and the author answered that it uses an event loop, so if you want it otherwise, go away and use something else, like Riker... So I went away :) ... I would assume this kind of behaviour has been corrected meanwhile (I mean the library, not the comms), because otherway, it's just a Node written in Rust. My 2c :)