-
Notifications
You must be signed in to change notification settings - Fork 170
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
Policy chain - first version #450
Conversation
Generated by 🚫 Danger |
7f135dd
to
4983ecf
Compare
apicast/src/policy.lua
Outdated
local _M = {} | ||
|
||
local setmetatable = setmetatable | ||
local policy_chain = require('policy_chain') |
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 about requiring only what is needed? require('policy_chain').PHASES
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.
That would not really save anything. The whole file is executed and evaluated anyway.
And it would require unrolling it back when we need second property from that module.
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.
👍
policy
no longer depends on policy_chain
, so this no longer applies.
apicast/src/policy.lua
Outdated
policy[policy_chain.PHASES[i]] = noop | ||
end | ||
|
||
return policy, mt |
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'd document what this method returns as I think returning the mt
might be a bit counter-intuitive. I think we should document that it's returned so policy.new
can be overriden. Any other reason?
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.
That is the only reason so far. I could also store it in _M
like _M.class
or _M.mt
. Not sure what is better though.
But for sure has to be documented as this is public API for new policies.
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'll try to set the mt
as metatable of the returned module. Then you could get it by getmetatable
. Maybe it won't cause an infinite loop :)
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.
In the end went with not returning it at all and letting the user to decide what to do with it. They should upvalue the new function to a variable and call it later.
@@ -0,0 +1,33 @@ | |||
local setmetatable = setmetatable | |||
|
|||
local _M, mt = require('policy').new() |
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 should probably call new()
with a name. Otherwise, it will use the default one.
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.
Good point!
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 the policies are now initialized with names 👍
319b2e4
to
7624cd7
Compare
@@ -55,9 +55,9 @@ local function ttl() | |||
end | |||
|
|||
function _M.global(contents) | |||
local module = require('module') | |||
local context = require('executor'):context() |
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 will not work when APICAST_MODULE
is set.
88ab50d
to
7d4d450
Compare
@@ -1,7 +1,7 @@ | |||
local _M = {} | |||
|
|||
local cjson = require('cjson') | |||
local module = require('module') | |||
local context = require('executor'):context() |
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 won't work when APICAST_MODULE
env is set.
apicast/src/executor.lua
Outdated
local resty_env = require('resty.env') | ||
|
||
if resty_env.get('APICAST_MODULE') then | ||
return require('module') |
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.
Maybe we should do this in the apicast module itself? To keep the compatibility with the old module system. Basically allow people to replace the APIcast module. But we need to figure out how to allow them to require it but to outside return their module.
Maybe this belongs to the policy_chain.build where it defaults to the apicast module?
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 about doing this in the local_chain
module?
When building the local chain, the default is require('policy_chain').build({ 'apicast' })
. I think we could check the env 'APICAST_MODULE' and do require('policy_chain').build({ 'module' })
instead if it's set.
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.
Hmmmm. That sounds good 👍
spec/proxy_spec.lua
Outdated
@@ -66,7 +66,7 @@ describe('Proxy', function() | |||
assert.same('function', type(proxy.post_action)) | |||
end) | |||
|
|||
it('finds service by host', function() | |||
pending('finds service by host', function() |
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 needs to be moved to the find service policy spec.
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.
Done.
spec/proxy_spec.lua
Outdated
@@ -75,7 +75,7 @@ describe('Proxy', function() | |||
assert.falsy(proxy:find_service('unknown')) | |||
end) | |||
|
|||
it('does not return old configuration when new one is available', function() | |||
pending('does not return old configuration when new one is available', function() |
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 needs to be moved to the find service policy spec.
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 think this one belongs to configuration_store
. In fact, the same thing it's already tested there. I think we can just delete this test.
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.
Yeah. 👍
There are some commits here already included in other PRs (curl in benchmarks, DEBUG=1, etc.) |
This also moves one of the tests marked as 'pending' in the proxy specs to the new file.
Simple policy to be used in the tests. It will allow us to verify that the code define in the module for each phase is executed.
…y the apicast policy The policy_chain module initializes a chain with the apicast policy if none are specified, but I think that making the initialization explicit here improves readability.
As the documentation of the method says.
f3e5fbf
to
34d5a94
Compare
The module is designed so its users call phases() instead.
9deb048
to
e1a63cb
Compare
In fact, the same thing it's already tested there.
freeze() does not need to be exposed. We can remove it and perform the operation inline as it's just setting one attribute to true.
8ada7d8
to
ef63d2d
Compare
ef63d2d
to
95af30e
Compare
@mikz I addressed all the comments you and me wrote. I think this is ready. |
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 think this looks great! 👍 We can verify the APICAST_MODULE support later. I suspect there will be issues because the old modules don't export context. But we will solve that when the time comes.
Early prototype of how we could chain policies.
Policies can export data that is stored in read only structure and resolved in order they are defined in.
So values can be overlaid, but not overridden and only the latest one is being used.
This would allow overriding some internal structures being passed between policies.
Context object is passed to each policy phase invocation method. This context object has last layer mutable so policies can pass data.
Policy chain is itself a policy. All phase methods are compatible. So policy chain can contain policy chains.
This is used to split the chain into two: global and local. Global chain is responsible for loading configuration and local can be created based on downloaded configuration.
TODO