On Monday, February 27, 2017 at 8:59:46 AM UTC-6, David Schmitt wrote: > > Hi folks, > > I've written down the design in README format now. This should make for a > easier to ingest from a module developer's perspective. Meanwhile I've also > had a shot at a hardcoded implementation of this, and it is technically > possible to implement this too. >
Thanks for your efforts on this documentation. It helps clarify your view. I think you have some good ideas here, but I also think that what you've presented, as you've presented it, is not a viable replacement for the type & provider system we have now. Moreover, there remain important areas that I would dearly love to see documented, and one or two longtime sore spots that this proposal seems to be missing the opportunity to address. *Big picture items* *Multiple implementations / implementation selection* In splitting resources into "definition" and "implementation", the proposal adheres to a *form* similar to the current system's, but it seems to have fundamentally different design goals. I've always interpreted the present type / provider system's separation of resource interface from implementation first and foremost as a means to accommodate multiple implementations. The one most appropriate to the target system is chosen from among those available. I think that's a sound design approach; I like it, and it has served Puppet well. As far as I can determine, however, the proposal loses that completely -- I see no means to support multiple implementations at all, much less means to match an implementation to the target system. *Inadequate interface documentation* As I said earlier, one of the biggest problems with the current system is inadequate documentation. As it now stands, the proposal's documentation does about as well as the docs of the current system. Missing is information about how the runtime environment is intended to use the defined objects and methods -- for example, under what circumstances it will instantiate / invoke them, how many times per transaction (partially addressed in the doc), at what point(s) in the transaction. What may the environment do with the object returned by get() and its contents (i.e., must implementations assume that the environment may modify them)? Is there anything the environment is required to do with them? What may an implementation do with the object passed to set() and its contents? Is there any expectation about relationships between the objects provided by get() and received by put()? Similarly, are the "utilities" provided by the runtime environment supposed to be the only mechanism by which implementations interact with the host Ruby environment? The only mechanism by which implementations interact with the target system at all? *Pushing new responsibilities onto resource implementations* The minimalistic approach to defining the interface for resource implementations has the inevitable effect of making the host environment incapable of some of the tasks that it presently performs, leaving the onus on resource implementations to fill the gaps. For example, since there is no way for the environment to retrieve the state of a specified individual resource, and because some resource types cannot feasibly be enumerated, the environment cannot, in general, determine whether resources are in sync. Only resource implementations can be relied upon to do that, and then only in the context of their put() methods. Similarly, although I definitely like that a logging utility is made available to resource implementations, it seems that most responsibility for logging now falls on resource implementations as well. Currently, the environment handles a fair amount of that. It seems likely that moving the responsibility to resource implementations will not only make them more complicated to write, but will also reduce the consistency of log messages. *Terminology Changes* The proposal seems to gratuitously change established terminology. What we now call "properties" are to be referred to as "attributes", which itself is currently used in a broader sense. "Types" become "definitions"; "providers" become "implementations". Why? However well or poorly you like the established terminology, it *is* established. The proposal seems to be offering variations on these existing things, not entirely new things, and changing all the terminology is likely to be more harmful than helpful. *Specific features* *Attribute and parameter validation* Validation ought to be performed during catalog building, thus it needs to be adequately addressed by type "definitions". I am dissatisfied with the proposal's provision for that. The Puppet type system is very expressive, but it can also be very arcane. I maintain that it is a mistake to rely exclusively on the type system for validating "attributes" or "operational parameters". Moreover, I think the proposal is missing an opportunity to provide for multiple-attribute, multiple-parameter covalidation. This has been requested on and off for a long time, and this proposal is a great opportunity to finally put it in place. *Transaction progress and state* Resource implementations are afforded only indirect information about transaction context. For example, the docs say that "The implementation should not try to cache state beyond the transaction", but how, exactly, is the implementation supposed to recognize the end of a transaction? It would be highly desirable for implementations to have means to at least opt in to messages about transaction lifecycle and events. For some purposes, it would be useful to have a way for type implementations to be able to communicate with each other within the scope of a transaction. *Details* *"Read-only" vs. "init-only"* I understand -- I think -- the distinction you're drawing here, but it's confusing. Surely if a resource does not yet exist, then *all* its attributes are logically written when it is created / initialized. I could understand that is a plausible exception to read-onlyness if not for the explicit provision for init-only attributes. If you want to maintain both of these cases among the attribute metadata then please rename one of them. For example, perhaps "derived" or "internal" would describe what you mean by "read-only". *Compound resource names* I suppose that compound namevars are a topic that you hoped to avoid in your push for simplification, though it looks like they might not be hard to support via the interface you have already described. This is a weak area for the present system, and one that I think any replacement should support well and and fully. *Attribute / parameter clashes* By specifying attributes and operational parameters via separate hashes, the proposed system affords the opportunity for name collisions between these. That also makes resource definitions less cohesive with Puppet overall, because in the Puppet language, attributes and operational parameters are specified together, in the same syntactic construct. I fully understand the differences between these, but I suggest they not be reflected by a complete separation between their specifications, such as the proposal currently provides. *Resource implementations that become usable during a run* It is only relatively recent that Puppet implemented the long-desired feature of supporting resource providers that become usable as a result of other resources being managed earlier in the same run. It is not clear whether or how that would be supported under the proposal as currently presented, but this is a feature that I do not think we want to lose. *Environment for commands* If resource implementations are expected to use the 'commands' utility for running system commands, then that utility needs to provide a mechanism for specifying environment variables that must be set in the environment of those commands. It is furthermore highly desirable that it be possible for the values and maybe even the names of those variables to be drawn from the values of a resource's operational parameters. *Host object* The doc refers in a couple of places to a "host object". What is this? What are its methods and properties? How is it to be used? *Overall* I can see that a lot of thought and effort has gone into this proposal. I've focused mostly on criticisms, but I want to acknowledge that there's some good work here. Nevertheless, I regret to say that I dislike the overall proposal in its current form. It could be improved to some extent by more complete documentation, but documentation notwithstanding, I think it focuses too much on simplification and on the resource itself, and not enough on how resources will be used by and interact with the larger system. I do not doubt that the proposed API can be implemented, and that's indeed a mark in its favor. If it is intended only as a simpler *alternative* to the present system, then many of my more significant concerns are irrelevant. To the extent that this is being positioned to ultimately replace the current system, however, it doesn't provide everything it needs to do, it misses providing some things it should do, and I'm dissatisfied with the way it provides some of the things it does. John -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/a9e20030-bd53-4360-ba96-0b5a148c1130%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.