Skip to content
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

cross modules stream/http shared dict #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

alonbg
Copy link

@alonbg alonbg commented Sep 7, 2016

This addresses issue #25 - cross modules shared dict.
Tested (including adding/removing dicts and reload) but tests still need to be added.

I'v covered different ways to do this. Most were either over complicated or/and risky.
This one is quite simple - a module references the other module zones only during post-configuration phase. It works as it relies on the fact (to my best knowledge) that across all pushed dict functions, zone->data is ngx_stream_lua_shdict_ctx_t or ngx_http_lua_shdict_ctx_t which are cast-interchangeable (they are aligned in the attributes that they are referenced to).
The single non compatible attribute is ctx->main_conf but it's only accessed during configuration phase where each module takes care of it's own.
Another big advantage is that it works without any changes to lua_ngx_module. Until http module adopts the change, a dict should be configured in http context for this to work.
This is of course not ideal but it's by far the simplest way.
If possible, it would be best to make these structs fully aligned or even better including a common header file for this. Another TODO is "selectively sharing dicts".

test configuration attached
nginx.txt

@alonbg alonbg force-pushed the cross_modules_shared_dict branch 4 times, most recently from a15851e to 60df5b2 Compare September 8, 2016 07:42
@@ -13,6 +13,7 @@
#include "ngx_stream_lua_shdict.h"
#include "ngx_stream_lua_util.h"

extern ngx_module_t ngx_http_lua_module;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't quite like the fact that the ngx_stream_lua_module always requires ngx_http_lua_module, which is not acceptable when the user does not need the http subsystem at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should try to detect the presence of ngx_http_lua_module automatically in the build system (i.e., the config file) and fork the logic with C macros.

}

if (&ngx_http_lua_module == shm_zone->tag ||
&ngx_stream_lua_module == shm_zone->tag )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: || should be at the beginning of the continued line. See other similar places for examples.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should make constant value on the RHS of the ==.

if (&ngx_http_lua_module == shm_zone->tag ||
&ngx_stream_lua_module == shm_zone->tag )
{
zone = ngx_array_push(&all_zones);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach is risky since the shdict implementation of ngx_http_lua_module might be different than ngx_stream_lua_module (due to different versions of these modules, for example). It will lead to hard-to-debug issues when these two modules' implementations are incompatible in terms of the shm zone storage layout.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The safest way, IMHO, is to abstract the shm dict implementation out and make both these ngx_xxx_lua modules share it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agentzh You mean share the a common header file ? Where would this file reside ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alonbg I mean creating a ngx_meta_lua_module and make both ngx_http_lua_module and ngx_stream_lua_module depend on it.

Copy link
Author

@alonbg alonbg Sep 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agentzh Yes this was your original idea :) but to avoid collision [and allow coexistence of old and new] meta's shared dict directive will need to have a different name or stay with the name lua_shared_dict but restricted to the configuration main part (outside both http and stream contexts). Which option do you prefer ?

Copy link
Author

@alonbg alonbg Sep 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The risk is still there I believe since the ngx_meta_lua_shdict_ctx_t which would be defined in all three modules might be different.

Copy link
Member

@agentzh agentzh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. But this PR still needs quite some work I'm afraid :) Thanks!

ngx_stream_lua_inject_socket_option_consts(lua_State *L)
{
/* {{{ socket option constants */
#if (NGX_HAVE_TRANSPARENT_PROXY)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, do not include unrelated changes in the PR. Thank you.

@agentzh
Copy link
Member

agentzh commented Sep 19, 2016

@alonbg BTW, the Travis CI testing is broken on this PR, as evidenced below.

@alonbg
Copy link
Author

alonbg commented Sep 19, 2016

@agentzh thanks for taking the time to comment.
The other changes are simply a miserable rebase out of place. I'll rewind.
I agree with your approach. Ill see what I can do.

@johnyin123
Copy link

2 or more share dict, when reload nginx, some dict lost .

17 http {
18 lua_shared_dict http_dict 1m;
19 lua_shared_dict http_dict1 1m;
20
21 server {
22 listen 8888;
23
24 location /udp {
25 content_by_lua_block {
26 local http_dict = ngx.shared.http_dict
27 http_dict:set("udp", ngx.var.uri)
28 local stream = http_dict:get("stream")
29 if stream == nil then
30 ngx.say("udp OK")
31 else
32 ngx.say("udp ok " .. stream)
33 end
34 }
35 }
36 }
37 }
38
39 stream {
40 lua_shared_dict stream_dict1 1m;
41 lua_shared_dict stream_dict2 1m;
42
43 server {
44 listen 127.0.0.1:9999;
45 content_by_lua_block {
46 local http_dict = ngx.shared["http_dict"]
47 local http_dict1 = ngx.shared["http_dict1"]
48 http_dict1:set("test", "test")
49 -- ngx.log(ngx.ERR, "get http shdict = " .. http_dict:get("udp"))
50 http_dict:set("stream", "xxxx")
51 }
52 }

telnet localhost 9999
./nginx -s reload
telnet localhost 9999
so the secound http_dict1 nil.

@agentzh
Copy link
Member

agentzh commented Nov 3, 2016

We need a separate ngx_meta_lua_module for this. It's wrong to do such things in either ngx_stream_lua_module or ngx_http_lua_module. Either way is wrong and fragile.

@alonbg
Copy link
Author

alonbg commented Nov 8, 2016

@agentzh, I'm convinced btw. I'll start working on ngx_meta_lua_module when I find the time.
Thanks

@bjne
Copy link

bjne commented Feb 27, 2017

What is the status on the ngx_meta_lua_module?

@thibaultcha
Copy link
Member

Here is my alternative proposal to this feature: openresty/meta-lua-nginx-module#76

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants