-
Notifications
You must be signed in to change notification settings - Fork 83
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
Remove method_missing and make Chef::Resource unspecial #117
Conversation
Note: most of the deprecation feedback is based on edges discovered during the implementation at https://github.com/chef/chef/tree/jk/missing_method_missing . That branch still needs to handle Chef::Provider and add a number of deprecation (and stack trace) tests. |
|
||
- Switches to explicit methods for Chef recipe DSL instead of method_missing | ||
- Removes all special treatment of classes in the Chef::Resource and Chef::Provider namespaces | ||
- Automatically adds resource DSL for all named descendants of Chef::Resource, no matter what their namespace |
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 would rather never create them for descendants per se, just should be any class that calls Chef::Resource.provides
, no matter what that class is. We already have enough issues with descendant tracking for providers as is :-( I think that's basically what you mean 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.
I'm actually just using def self.inherited
on Chef::Resource
, which seems to do the job. I'd like descendant tracking to go away, but we have to do this in chess moves, or we get RFCs like the last 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.
As far as the everyone vs. no one decision, here are my thoughts:
- I agree with you from a cleanliness standpoint: everyone should call
requires
- From a practical standpoint this would make a lot of resources stop working
- I think that, as you have proposed in the past, the real Resource base should be a mixin that we will create later. That is the point at which we get to do things that really cut backcompat deeply, because it won't affect existing Chef::Resource derived stuff.
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.
Recording the name on .inherited
is fine, as long as the system recognizes calling provides manually later and removes the very-briefly set incorrect name. As it stands, the NodeMap code doesn't do that.
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.
Also because I have to say it, "This won't be thread safe" but I don't think anyone cares about multi-threading the initial cookbook loading process yet, so as long as we all remember it should be fine :-)
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.
Believe me when I say I am keenly aware :) I am hoping we can get to the point where separate chef runs can go in separate threads, among other things. I am incredibly uncomfortable with our use of globals to store things that users do in a cookbook in a single chef run. But, baby steps ...
@coderanger I modified the provides / does_not_provide sections, and provided an overview of what would be affected in Chef 12 (couple of extra features, and deprecation warnings). |
the resource being declared is often not on the stack, making debugging harder. | ||
|
||
Here we propose that all resource and definition DSL be added to | ||
`Chef::DSL::Recipe` as actual methods, as they are created, so that they can be |
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.
Either you should use a cleanroom style class instead or Chef::DSL::Recipe should be converted to a cleanroom style class. Probably the latter.
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.
The actual solution I implemented was a module named Chef::DSL::Resources
, which I include into Chef::DSL::Recipe
. But I'm unclear what the purpose of a cleanroom style class is here, and whether that solution addresses what you are talking about? Can you clarify?
So I think we have hit a fork in the road. If we want to remove |
I'm broadly in favour of this RFC, and my initial thinking was that removing |
It's not necessary to remove |
Specifically, the rule could be: (Edit: it turns out this rule is basically in there, in an even more relaxed version; it's just implicit and supports provides? on anything as long as DSL is declared anywhere.)
|
Actually, the RFC is even more relaxed than that, without breaking anything: If we are OK with the rule "you must declare the name of a DSL in a |
The final thing we could do--which would still be a big net gain in my opinion--is not deprecate method_missing at all, but still implement explicit methods everywhere. All of the benefits we get here, we would continue to get. The system might be hard to understand in cases where you do a hidden I'll admit I'm not a fan of this approach, and would rather not change to it, but I'll definitely take it if we feel that being able to say essentially |
OK, here's the full description of the issue we're discussing, for those following. Right now, the Provides system has a class MySuperFileResource < Chef::Resource
def provides?(node, resource_name)
resource_name == 'super_file'
end
end
class MySuperFileProvider < Chef::Resource
def provides?(node, resource_name)
resource_name == 'super_file'
end
end In Chef 13, with this proposal, typing class MySuperFileResource < Chef::Resource
provides 'super_file'
end
class MySuperFileProvider < Chef::Resource
provides 'super_file'
end This isn't too onerous-- class MySuperFileProvider < Chef::Resource
def provides?
true # provides any and all resources, because it is THAT awesome
end
end Or other arbitrary criteria that allow for arbitrary names. provides 'name' doesn't support that. We would be causing those cases to be impossible. I'm personally OK with it. I'm uncomfortable with the way Rails does this with ActiveRecord, and at any rate, I don't think we intended it, it just happened as a side effect and no one is actually using it this way. If we add the feature in later, we should do so intentionally. cc @jonlives |
I'm with you @jkeiser - providing a regex of DSL entries seems crazytown to me. |
@coderanger @lamont-granquist one more question: once we deprecate the implicit magic entirely and only support |
@coderanger @lamont-granquist just wanted to check whether we're in good shape on this or if there's anything else we need to hash out before tomorrow. I've got a working patch I'd like to get in soonish, so that it's cleared out and we can move on to next things. As to the last question, I modified the RFC to deprecate implicit |
|
||
The implications of this are that we have to scan every single resource when | ||
you type `blah` in a recipe, just so we can catch this one. In Chef 12 we will | ||
issue a deprecation warning and tell you to do this instead: |
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.
Might want to be clearer that this will be removed in Chef 13.
@jkeiser I think we should probably just get rid of provides_nothing at this point, it is extra stuff to maintain and that isn't a use case that is currently supported (defining a class under |
Yeah. I'm fine with removing |
Yeah, provides? can be less lazy and can be moved somewhere right after we first build the node. The right solution to this probably does away with descendent tracking completely and requires every provider that uses dynamic resolution to have a provides? line. We should also be able to refactor into using a single node map at the same time -- although we might need to be careful with handling the case of having multiple providers that can be returned by dynamic resolution with the single node_map (I'll really need to sit down with the code to figure out that, not sure it works in my head). I'd like to see all of that internal cleanup get done. @jkeiser if your branch doesn't cover all of that, you should probably complete what you can get done so that I can patch on top of that. |
Yeah, I spiked on getting everything into a single node_map, but it wasn't necessary to get this done so I didn't finish. We can definitely chat about that. |
Yeah, in the shower today I became not sure that works the way that I want. Generally would be good to push your code and start to more collaboratively hack on stuff. |
@lamont-granquist @coderanger note: I wrote up a new implication of forcing people to use I think there are ways we could simplify the resolvers by modifying the rules, but I think that merits a whole separate topic and RFC. @lamont-granquist I think I have enough data now to write out the thinking about node maps and such, in a way that's intelligible enough to detect problems before we spike. I'll write it out as soon as I can manage, and we should find time to talk. |
@chef/rfc-editors this one's decided and ready to rock too! |
ping @chef/rfc-editors can we get this merged before tomorrow's meeting, please? |
yeah code is merged and this is gonna ship soonish. |
cc @coderanger @lamont-granquist