poga / actix-lua

Safe Lua Scripting Environment for Actix
MIT License
121 stars 13 forks source link

rust libraries in child actors #23

Closed Arnaz87 closed 5 years ago

Arnaz87 commented 5 years ago

Is your feature request related to a problem? Please describe. We're making a framework on top of actix-lua, which has lua bindings for various rust libraries, that's why I need access to the vm from rust before running lua, to set the bindings as globals. We're now starting to actually use the actors functionality and create actors from the lua code, but the child actors don't share globals with the parent actors, and there's where the bindings are.

Describe the solution you'd like The optimal solution would be just that all actors shared globals, but I guess that's not possible for safety reasons and whatnot. Then the next best solution is to somehow have access to the child actor's vm in rust, as I have already with the main actor, somehow intercept the actor creation process to setup the globals we need.

Describe alternatives you've considered Pass the libraries as messages. That's ugly IMO and not even possible because of the message types limitation (I don't know why that restriction but that's out of the scope)

Maybe there's another way to pass data to child actors different than messages, or a shared space somewhere (either in lua's or rust's side), or maybe creating a shared space is a better solution than giving access to what I suggested before.

poga commented 5 years ago

Why you need to share globals between actors? Actor is suppose to be an encapsulation. I think it's a big misuse of actor model if you need to share states between multiple actors.

In actix-lua, every actor is an isolated Lua VM. It's intentionally designed as it is.

Communicate by passing messages is one of the fundamental characteristic of Actor model. You need to rethink your architecture if it becomes an obstacle.

poga commented 5 years ago

Also, this issue looks like a XY problem. What's the problem you're actually trying to solve?

Arnaz87 commented 5 years ago

I already explained what i'm trying to achieve in the first paragraph, it's a lua framework, I don't need to share state, just the framework libraries. The easiest way is to share globals, but I mentioned some alternative solutions, and by explaining specifically what i'm trying to achieve maybe you can help me with it.

poga commented 5 years ago

IMO Sharing libraries is essentially sharing states.

The first paragraph is exactly why I think it's a XY problem. If all you want is to share context with a Lua script, you can create a sandbox with Lua loadfile and setup an ENV for the loaded chunk. Or even simpler you can just require the script and it automatically share the same scope.

What's the goal you want to achieve via creating a new LuaActor at runtime?

Arnaz87 commented 5 years ago

The framework is not intended for rust users but for lua users, and I want lua users to be able to create actors, which they can with ctx.new_actor, but that actor doesn't share the libraries of the main actor. The libraries are written in rust, so a lua script to setup the environment doesn't cut it. I need either access to the child actor's vm from rust, or a way to pass libraries from the first actor to the second, and the libraries are composed of lua and rust functions, which cannot pass through messages because it panics with not yet implemented

Arnaz87 commented 5 years ago

That's the kind of libraries I need access to from lua, that can't be set up by a lua script because the implementation of the functions is rust code. I need to either run this code again on each child actor, or have those functions shared between actors somehow.

This is how I setup the environment for the first actor, this is create_vm, some of it can be lua but most of it can't.

Arnaz87 commented 5 years ago

Another possible solution could be to complete the message variants, to make it possible to pass functions, user types, and everything else, so that we can pass the bindings from the main actor to the children. How good of a solution is it compared to "access to the children vm", and how feasible is it?

Arnaz87 commented 5 years ago

I understand that you don't like sharing state and that it's missing the point of the actors, I suggested it at the beginning but that's not what I need, it was a possible mechanism to solve my problem which you reject it and I get it.

In my project there is some stuff I do to a lua environment that can't be done in lua itself, with the with_vm function in the builder I can do that kind of stuff in the main actor, but it's a big limitation if the child actors cannot be modified the same way, for example what if some lua code needs the lua debug library? just a script setup.lua doesn't allow one to deliver it, it can only be done from rust.

My current idea is, instead of giving to the builder a single custom vm, give it a callback function that actix-lua will invoke to get a vm machine for each actor it creates. That ensures each actor is on its own different environment and, while it allows users to have shared state, they have to go out of their way to do that because rust has strong requirements to let a user do that, and it's a big benefit for the cost of giving some responsibility to the user, which again, users are expected to by default let actix-lua create on it's own the vms, overriding that behaviour is doing it the hard way.

Arnaz87 commented 5 years ago

Instead of

LuaActorBuilder::new().build_with_vm(Lua::new())

do

LuaActorBuilder::new().build_with_vm_callback(|| { Lua::new() })
Arnaz87 commented 5 years ago

This is the callback I intend to give to actix-lua (needs a bit of cleanup and move the lua execution to on_started)

poga commented 5 years ago

actix-lua and actix are not designed to spawn short-lived actors at runtime. (see https://github.com/actix/actix/issues/77). Therefore, ctx.new_actor is a badly designed API (since it encourage people to spawn random actors at runtime). It's going to be removed in the near future.

On the other hand, actix-lua is low-level. Instead of expose it to the users directly, you should wrap it with a domain-specified interface for your user.

poga commented 5 years ago

To avoid further confusion, ctx.new_actor is removed by https://github.com/poga/actix-lua/commit/06003aeca35c94e1d148bc1e99b0ca063417262a.