-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: implemented a configure_by_lua phase #1259
base: master
Are you sure you want to change the base?
Conversation
85902f9
to
69f7817
Compare
@thibaultcha |
PS. You could use priviledge process to detect configure change and send reload signal. And the template render could be implemented in Lua, so no other dependency is required. |
@spacewander This is precisely what we have been doing for the past few years, and what this PR tries to get rid of :) The goal here is to avoid having to depend so heavily on templating all the time to configure our applications. Additionally, templating causes huge headaches to users who need to make their own modifications to their Nginx configuration file, not only to learn it but also for each upgrade with configuration changes. Really, the goal here is to not have to do that anymore. |
Especially considering the maintainability cost seems to be relatively low. No Nginx patch required, a dependency on an init, process that is very unlikely to ever change, and a self-contained patch in the codebase. I believe the ability to configure servers and location blocks would be possible by respecting the same constraints as well. |
|
||
|
||
char * | ||
ngx_http_lua_configure_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like all the code duplications in this C source file. It makes the code base harder to maintain and sync new changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can definitely improve it :) Which area? The context runner and/or the shm configure API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thibaultcha Almost all the code in this C source file is duplicated C code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agentzh I just added a new commit which introduces ngx_http_lua_shared_dict_add
, which factorizes all of the shared code for shm create for lua_shared_dict
and ngx_configure.shared_dict()
.
As stated before, the code related to parsing and running the _by_*_block
and _by_*_file
directives of this module are already always duplicated - this feels outside the scope of this PR, but if you want me to address this, please advise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the Lua phases code is duplicated already, I just followed the pattern.
What exactly are you referring to?
The thing is if the config phase handlers can call these functions, then we should make it that way. I don't want to maintain 2 duplicated copies of configurations. Also, how do you handle config directive overriding and inheritance here? Seems like you already bypass the nginx config system entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how do you handle config directive overriding and inheritance here? Seems like you already bypass the nginx config system entirely?
There is no inheritance involved here since we only support configuration of http
(or above) level directives, and this is deliberate.
Ultimately, I do wish to support lower levels of configuration as explained in the PR (server
, location
...), but without it there are no need for supporting inheritance yet.
What exactly are you referring to?
I was reffering to the only part of the code that I see is duplicated from other parts of ngx_lua, and that is the ngx_http_lua_configure_by_lua
and other handlers that run the Lua code for this phase.
If not, then I am not sure what you are referring to when you are saying things are duplicated?
|
||
if (lmcf->shdict_zones != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also makes such optimizations no longer exist. I'm kinda proud of the concept that you do not pay for the features you never use :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? We only create the shdict metatable if we need it still (via lua_shared_dict
or ngx_configure.shared_dict()
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thibaultcha We used to save the metatable when lua_shared_dict is not configured in nginx.conf
. This is a minor thing though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thibaultcha It seems that you essentially created a second parallel configuring code path for those config directives we already have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used to save the metatable when lua_shared_dict is not configured in nginx.conf.
And we still do, I made sure of that, this method has been renamed to reflect the change but both of its calls in the codebase are enclosed within conditions. I could re-add the safeguard condition in here too just in case.
It seems that you essentially created a second parallel configuring code path for those config directives we already have.
All of the Lua phases code is duplicated already, I just followed the pattern.
Regarding the add shm API, I can certainly improve it - I originally didn't want to modify existing code too much by fear the patch would be refused if so.
Regarding the timers code, I was thinking of coming up with a more generic way of setting integer values onto the lmcf
structure (we could follow the NGINX pattern with ngx_conf_set_num_slot
and the likes) but that seems unnecessary for only 2 fields as of today and considering it would result in a lot more code.
return NGX_CONF_ERROR; | ||
} | ||
|
||
*zp = zone; | ||
|
||
lmcf->requires_shm = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was duplicated (as in the master branch) - we now only set it from ngx_http_lua_shared_memory_add
.
@@ -122,9 +121,7 @@ ngx_http_lua_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, | |||
return &ctx->zone; | |||
} | |||
|
|||
n = sizeof(ngx_http_lua_shm_zone_ctx_t); | |||
|
|||
ctx = ngx_pcalloc(cf->pool, n); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just cleaning up here but I can revert if not desired.
24d031b
to
545deb0
Compare
@thibaultcha I appreciate your exploration in this direction. I'm thinking about maybe we could make this work on a much lower level, by dynamically configuring all the nginx main/http/stream/server/location blocks in Lua. Your approach looks like we will simply duplicate all the existing nginx configuraiton directives in this new facility, which does not have a future IMHO (not to mention there might be an infinite number of 3rd-party nginx modules out there providing their infinite number of possible directive that could interact with OpenResty) :) If we want to get rid of nginx.conf, then let's do it in a thorough way :) Just my 2 cents. |
Yes, this is exactly my point and my intent on the long term (as explained above). The current patch is more of an intermediate phase for the nginx
Maybe not all :) This approach would already be quite helpful imho - we've been wanting for years to only allocate the lua_shared_dict that our customers' dynamically configured instances need, without requiring of them that they learn or modify our nginx configuration templating system (that we wish to get rid of in the long term). I believe a lot of users would be happy to allocate shared dicts from the Lua-land (I have witnessed many asks for it over the years in the mailing list, issues, or chats...).
Agreed. But it is not because we cannot please everybody that we should please nobody :) Covering the directives that are used the most often (like One solution I thought of (I did not explore its feasibility) was to avoid creating structures representing the state of the configuration like this: ngx.server.my_server:add_location("/") Which would become a maintenance nightmare, but instead supporting a more lose API, like: ngx.configure.append [[
server {
listen :8080;
location {
return 200;
}
}
]] Maybe the final solution will be something in the middle.
I am of the same opinion, but I also think that this intermediate step is a good one to take until more APIs are added to this phase that will ultimately allow us to get rid of nginx.conf. |
I very much want to highlight the following sentences from this PR's opening thread:
The current proposal is to iterate slowly towards that goal with a few APIs that would already be helpful. If you prefer the idea I have outlined above, or if you have a better one altogether that you wish to share, or if dynamically configuring nginx is not something that OpenResty wishes to achieve, I am fine with this, please do let me know! :) |
@thibaultcha I do understand your intention but unfortunately I don't see this PR as an iterative approach to the right direction from the perspective of an implementator. This patch adds quite some maintenance overhead with very little real world merit IMHO. |
Down the line, being able to append or "execute" blocks of NGINX config (even as strings to lower the implementation requirements) from init_by_lua would be a godsend for server management tools. |
This pull request is now in conflict :( |
f924579
to
fef2581
Compare
This pull request is now in conflict :( |
This pull request is now in conflict :( |
This pull request is now in conflict :( |
This pull request is now in conflict :( |
This pull request is now in conflict :( |
This phase's purpose would be to allow the configuration of NGINX/ngx_lua with Lua scripts. This PR proposes a first draft with just a few APIs, hoping that more APIs can be added progressively.
Ultimately, I cherish the vision to some day being able to dynamically configure
http
,location
,stream
, and other blocks right from Lua.Example of what is currently implemented:
List of what is currently implemented:
configure_by_lua
phase (block/file) forhttp
contextngx_configure.shared_dict()
->lua_shared_dict
ngx_configure.max_pending_timers()
->lua_max_pending_timers
ngx_configure.max_running_timers()
->lua_max_running_timers
ngx_configure.env()
->env
lua_
prefix from directivesEverything is implemented via the LuaJIT FFI in the lua-resty-core sister PR located at: openresty/lua-resty-core#176.
My current goal is to get feedback, reviews, guidance... anything :) In the long term, I wish to gradually add more relevant API to this phase and make OpenResty more dynamic. If anyone can think of anything in the current implementation that would eventually impact this goal or limit future possibilities, please let me know.