On 2014-30-06 16:32, John Bollinger wrote:


On Saturday, June 28, 2014 9:54:25 AM UTC-5, henrik lindberg wrote:

    * Make application of defaults eager so that when a resource is
    instantiated, it will immediately get the registered and visible
    defaults (for missing attributes), at *that* point of time in the
    evaluation. This means that defaults become imperative (like variable
    assignment).



I had supposed that defaults worked that way already.  If currently they
get applied only at collection time, then does that mean that exported
resources don't get any defaults applied?


Not sure yet. I know defaults are applied very late, when the compiler does its "finish" - I think it applies to all resources. I also think that defaults are applied after collection has taken place.


    * When resource defaults are applied eagerly they are also available
    when doing collection (instantiation is naturally done before
    collection
    - otherwise there is nothing to collect).

    * There are edge cases where collection can be made at a point where
    all
    resources that the query matches (will match) have not yet been created
    (i.e. if the virtual resources are instantiated after the query is
    evaluated). There seems to be logic that tries to find everything
    (lazily at the end), but it is uncertain that it actually works
    correctly in all cases. What we propose for the defaults have no effect
    on this, it only changes what the resource attributes are when
    collecting.



These edge cases would be where collection of virtual resources of a
defined type causes new resources to be declared and/or resource
overrides to be applied?  Perhaps also cases where there are two
collectors over the same resource type, and one or both apply property
overrides?

I think these kinds of cases are problematic in general.  It is unlikely
that the catalog builder could ever reliably get them all right right.
In fact, I suspect that there are cases that haven't even a
theoretically correct result (with either evaluation scheme for resource
defaults).  It is wise to avoid being hung up on that.

ok, thanks.

    * We want to change the function 'defined' to return the state of the
    resource instead of just a boolean. Currently the concept of being
    "defined" is vague, the function returns true for all kinds of
    resources
    (virtual and exported) as well as those that are included in the
    catalog. We want to return some kind of status (that is "truthy" to
    make
    it backwards compatible), but that also tells if the resource is
    actually realized (in the catalog).



Ok.  Since it's already evaluation-order dependent to use defined() at
all, I don't think it's much worse to make it even more evaluation-order
dependent.


:-)

    (We agree that using the defined
    function is bad practice, but it is required to support certain
    use-cases that would otherwise be very painful/impossible to handle).



I think that depends on how generally you define the use cases and/or
what constraints you put on them.  But we don't need to go off on that
tangent here and now.


yep, tabled.

    * The File[foo][mode] syntax for lookup of a resource attribute will be
    more sane, as it will correctly produce the value at that point in time
    in the evaluation. It is either the value (explicit or default) that
    will end up in the catalog for a realized resource, or the explicit or
    default value of an unrealized virtual resource that *may* get a
    different value when it is later realized (if realized at all).



Not necessarily.  It is possible that a resource override will be
evaluated later.

yeah, Doh.

    Thus,
    with a combination of being able to know if a resource is realized or
    not, it is possible to also be certain that the value is the value that
    will end up in the catalog).



No, it isn't.  With all the overrides and lazy evaluation that can
happen, it is never possible to have localized advance knowledge of what
any resource parameter's value in the catalog that ultimately will be
produced.  Such a prediction may be possible if you have a view of the
whole manifest set (e.g. to see that there are no File overrides
anywhere in it), but that's inconsistent with a module-based approach to
organizing and using manifests.

Yeah, not worth trying to predict.

I see I will have another piece of candy to advise sweet-toothed people
to avoid for the sake of their teeth.  However much good that ever does.



    We believe that the construct with lazy default application was
    required
    when dynamic scoping was available, but we are honestly not sure about
    the rationale behind the current design.



Are you conflating the dynamic scope of resource defaults with applying
them in lazy fashion, or are these separate issues?  If you are
proposing to change the scope of resource defaults, then that makes this
a much more significant change than otherwise it would be.

Perhaps the rationale for the current design is to ensure that all the
defaults that apply to a given resource declaration are effective.
Consider:

class a {
   File {
     owner => 'alice'
   }
   include 'c'
}

class b {
   File {
     mode => '0660'
   }
   include 'c'
}

class c {
   file { '/tmp/foo': ensure => 'file' }
}

include 'a'
include 'b'
# include 'c'


yeah, that must be it.

It would be nice if the properties of File['/tmp/foo'] were not
dependent on which of classes 'a', 'b', and 'c' was evaluated first.


What we mean by eager setting of defaults would mean that the resource gets its defaults when the file { '/tmp/foo': ensure => file} is queued for evaluation. If the current runtime keeps track of both include locations for c, and applies the defaults dynamically, then the order of and be would not matter (with an eager application), but if c was included before a or b it would.

If we want to keep the order independent then they must be applied late (or appear to change dynamically throughout the evaluation).

    There are plenty of
    logged issues in Redmine regarding defaults, and collection, but that
    did not help us much as they are for a variety of versions, and for
    when
    dynamic scoping was available (plus a number of other issues where not
    fixed), so it is very hard to tell which of the old issues that are
    still relevant.



Dynamic scope is not completely dead.  Perhaps this is the time to kill
it (for resource defaults), but please be mindful that doing so is
likely to break a lot of code.

Yea, I realize this.

I think I have to let this idea sink in a bit before I can form a firm
opinion about it.  I started out very positive, but the closer I look at
the idea, the more it loses its shine.  That's not to say it wouldn't be
a net win, but there seem to be some trade-offs that I need to consider.


The two cases that we are concerned about is a) the ability to lookup resource attribute values, and whether this should return the currently known default values or not. We can see it as not looking up default at all, or lookup the default values as known at that point in evaluation. (Since resource overrides are also in play, and value is actually just a prediction), and b) collection of virtual resources since it is unclear what default values have been applied and can be queried...

The eager application of defaults is not a goal in itself.

And thank you for taking time responding on this! Much appreciated.

- henrik
--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

--
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/losv3u%24164%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to