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.

Reply via email to