lua-protobuf icon indicating copy to clipboard operation
lua-protobuf copied to clipboard

Multiple contexts

Open daurnimator opened this issue 7 years ago • 13 comments

Could you add the ability for multiple pb contexts within a single lua state? Ideally the API would be to make everything a method that passes the context around. e.g.

local pb_ctx = require "pb".new()
local pb_compiler = require "protoc".new(pb_ctx)
assert(pb_compiler:load(someproto))
local mytype = pb_ctx:type("Hello")


local pb_ctx2 = require "pb".new()
local pb_compiler2 = require "protoc".new(pb_ctx2)
assert(pb_compiler2:load(someproto)) -- where someproto contains a different/conflicting defintition of the same types.
local mytype2 = pb_ctx:type("Hello")

daurnimator avatar Mar 23 '18 05:03 daurnimator

It may easy to add this function, but I wonder it's useful...

starwing avatar Mar 31 '18 12:03 starwing

It may easy to add this function, but I wonder it's useful...

I have a use case where users of my server can upload .proto files; and then I use them to send messages on behalf of the user. I'd like each user to have their own context (or even have ability to have multiple)

daurnimator avatar Mar 31 '18 12:03 daurnimator

In this case, maybe users should be separated into different Lua state?

starwing avatar Mar 31 '18 12:03 starwing

In this case, maybe users should be separated into different Lua state?

It's running inside of openresty; which has one lua state per worker process; so that's a no go :(

daurnimator avatar Mar 31 '18 12:03 daurnimator

Okay, I will add plan to do this :-)

starwing avatar Mar 31 '18 14:03 starwing

multiple context support are landed :-)

starwing avatar Jun 04 '18 07:06 starwing

multiple context support are landed :-)

Thanks!

I see this initial version requires some dancing around to set the default context; make changes; then set the old context again. In future, would you consider changing things to be methods so that this dance isn't required?

daurnimator avatar Jun 04 '18 07:06 daurnimator

most usage use the global context, because this module is usually used in game engines. So people don’t like the method way to use it

starwing avatar Jun 04 '18 12:06 starwing

most usage use the global context, because this module is usually used in game engines. So people don’t like the method way to use it

Can always have both options: methods available on the context object; or use a default object when called on the module itself.

daurnimator avatar Jun 04 '18 18:06 daurnimator

It means we will prepare two version of functions: State as the first argument, or not. It may change a lot of code to retrieve state from argument, not from default_lstate(L) routine.

starwing avatar Jun 05 '18 02:06 starwing

It may change a lot of code to retrieve state from argument, not from default_lstate(L) routine.

Should be easy to swap it to check_lstate(L, 1);

To get the non-method versions, you could add lua-side wrappers? e.g.

function pb.load(...)
   return pb.get_default_context():load(...)
end

daurnimator avatar Jun 05 '18 09:06 daurnimator

I don't really like to adding Lua wrapper, as a single C module may easier to deploy and use. But it's a way to think of.

and, check functions are relately slow. it will getfield from registry, using type name string as key. thus means to calculate the hash value of string. So maybe it's better to passing it from parameter.

I will try to change pb module into a metatable of state type. but it may take times.

starwing avatar Jun 06 '18 04:06 starwing

and, check functions are relately slow. it will getfield from registry, using type name string as key. thus means to calculate the hash value of string. So maybe it's better to passing it from parameter.

For times when speed is critical, I've previously kept the metatable in an upvalue so that you can skip the lookup-by-string step:

	void *ud = lua_touserdata(L, index);;
	int eq;
        if (!ud)
		return NULL;
	if (!lua_getmetatable(L, index))
		return NULL;
	int eq = lua_rawequal(L, -1, lua_upvalueindex(upvalue));
	lua_pop(L, 1);
	if (!eq)
		return NULL;
	

daurnimator avatar Jun 07 '18 13:06 daurnimator