lua-protobuf
lua-protobuf copied to clipboard
Multiple contexts
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")
It may easy to add this function, but I wonder it's useful...
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)
In this case, maybe users should be separated into different Lua state?
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 :(
Okay, I will add plan to do this :-)
multiple context support are landed :-)
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?
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
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.
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.
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
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.
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;