brooklyn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Heneveld <>
Subject Re: [PROPOSAL/DISCUSSION] yaml DSL for invoking effectors
Date Tue, 07 Mar 2017 16:11:30 GMT

Hi Geoff -

 > Would it be too conservative to suggest that we don't do any more on this
 > until we do have a clear and compelling use-case in mind, when it will be
 > (I hope) a lot easier to see what way it should be done?

On the contrary -- it would be foolish to do something here /without/
a clear and compelling use-case to illuminate the way!


On 03/03/2017 09:46, Geoff Macartney wrote:
> hi Aled,
> taking your points in reverse order:
> 4.  I agree I can't see a good use case. If it's just doing a lookup with
> no side effects that would surely be more easily done by reading a sensor,
> not invoking an effector.
> 3.  It seems that the ability to invoke side effects is the main reason you
> would want to be able to invoke an effector; you're making the entity _do_
> something, maybe with a result; this suggests that...
> 2. would actually want to re-invoke the effector each time you read
> the config. But that sounds risky. In the CA server type example you
> probably wouldn't want to do this - you don't want to get a fresh public
> certificate each time you invoke the "sign-CSR" effector, rather it's
> something you do once when you initialise the entity that needs a
> certificate. I think the problem is that ...
> 1.  ...we don't have a clear idea of the use-cases we would need to
> support; I think there are likely several possible use-cases here, but that
> they are likely to have slightly different requirements, especially around
> point 2.
> Would it be too conservative to suggest that we don't do any more on this
> until we do have a clear and compelling use-case in mind, when it will be
> (I hope) a lot easier to see what way it should be done? As you say the key
> question is "_should_ we support..." and until we can clearly see "ah yes,
> we need that now, in order to do XYZ" maybe we shouldn't add it in the hope
> that it might be useful.
> I'd be keen to hear what @grkvlt thinks on this now, - Andrew?
> Geoff
> On Thu, 2 Mar 2017 at 11:59 Aled Sage <> wrote:
>> Hi Geoff,
>> I think long-term you're example would be covered by "Defining an
>> Effector as a Sequence of Tasks". That topic needs a lot more
>> (separate!) discussion, but in brief the idea is that an effector
>> definition is a first-class concept in the yaml (rather than using
>> "entity.initializers"); there would be yaml-support for defining a
>> sequence of tasks (e.g. execute some bash, do a http call, make an
>> effector call, etc). The yaml for "make an effector call" might end up
>> looking similar to this DSL discussion, but the context in which it
>> would be used is very different.
>> ---
>> I think the key question for this discussion is: should we support
>> effector-invocation via the DSL *for config values*?
>> If so:
>>   1. What use-case(s) are we trying to support?
>>   2. Should the effector be executed every time the config value is
>>      retrieved, or only once (and the result stored for subsequent lookups)?
>>   3. Should it be relied upon for side-effects (e.g. the CA certificate
>>      request example etc)?
>>   4. Or should it only be used for effectors that are getters/lookups?
>> For (3), I now lean towards the use of the EntityInitializer (and longer
>> term the "sequence of tasks" approach).
>> For (4), I'm not sure what a good use-case is (e.g. why can't we set a
>> sensor with that value, which might require extending the "source"
>> entity to add an additional "sensor feed" that retrieves the value for us).
>> For (2), I'm not sure what is most intuitive to users who are
>> reading/writing the blueprint yaml. It could be argued either way, which
>> suggests different users will expect different things! Therefore I'd
>> want to avoid relying on side-effects that you only want to happen once!
>> Aled
>> On 02/03/2017 10:30, Geoff Macartney wrote:
>>> I don't think we should just be thinking about a use-case like the CA
>>> server, which is maybe more limited in behaviour than the more general
>> idea
>>> here of being able to call effectors.
>>> In particular, what if you wanted to embed the effector invocation on
>> some
>>> entity within the code for an effector of your own entity?   i.e. you
>> have
>>> an effector on entity A that does some stuff when invoked, including
>>> invoking an effector on entity B?  (And maybe using the result when
>>> calculating its own result instead of storing it in a sensor).
>>> Is that something we'd want to support?    Is it a "stage 2" thing we
>> would
>>> add later on, some time after implementing the EntityInitializer
>> approach?
>>> G
>>> On Wed, 1 Mar 2017 at 12:32 Alex Heneveld <
>>> wrote:
>>> An `EntityInitializer` for this purpose is a nice alternative pattern --
>>> better than the child entity I suggested at #155 -- until we have
>> sequence
>>> effector YAML.  Is there anything `$brooklyn:effector` gives us that an
>>> initializer wouldn't do in a cleaner way?
>>> Best
>>> Alex
>>> On 1 March 2017 at 11:54, Aled Sage <> wrote:
>>>> Hi all,
>>>> I'd like to resurrect the discussion of whether the yaml DSL should
>>>> support invoking effectors.
>>>> See (That was
>> merged,
>>>> but Alex will revert it while we discuss if we want it, and if so then
>> how
>>>> it would behave).
>>>> If folk have additional use-cases and opinions to share, that would be
>>>> very useful!
>>>> ---
>>>> Below is what Andrew wrote in his email "[PROPOSAL] Enabling Effective
>>>> Effectors" on 30/05/2016, but it wasn't properly discussed then.
>>>>      ## Calling Effectors
>>>>      The YAML blueprint specification allows entities to be defined with
>>>>      sensors
>>>>      and to access the value of sensors for use in configuration.
>> However,
>>>>      although an entity can include effectors defined in the Java
>> classes,
>>> or
>>>>      using scripting languages (see above) and SSH commands, it is not
>>>>      possible
>>>>      to execute effectors and retrieve their results anywhere in a
>>> blueprint.
>>>>      The code in [brooklyn-server#155](
>>>> implements a
>> new
>>>>      function for the `DslComponent` class that can execute an effector
>> on
>>> an
>>>>      entity and evaluates to its return value. This new function is used
>> as
>>>>      follows:
>>>>      ```YAML
>>>>      $brooklyn:entity("other").effector("findInformation"):
>>>>         args:
>>>>           arg1: "value"
>>>>           arg2: 3.14159d
>>>>           arg3: $brooklyn:attributeWhenReady("host.address")
>>>>      ```
>>>>      Here we see the effector `findInformation` being evaluated with
>> three
>>>>      arguments, on the entity with id `other`. One of the arguments is an
>>>>      `attributeWhenReady` call, thus causing the execution to be delayed
>>>>      until
>>>>      the sensor data is available.
>>>> ---
>>>> Alex's philosophical objection in
>>>> klyn-server/pull/155#issuecomment-283077136 is copied below for your
>>>> convenience):
>>>>      right, so the use case is one entity wanting to get information from
>>>>      another. is there no way this can be accommodated using sensors? my
>>>>      philosophical objection is that we're introducing first-class
>>>>      support for a new class of dependency injection:
>>>>       1. simplest - static: DEP.x is set to a constant
>>>>       2. blocking - sensor: DEP.x can wait if a value isn't ready yet, ie
>>>>          it is a promise, $brooklyn:entity(SRC).attributeWhenReady(...),
>>>>          which once resolved is always taken as the value
>>>>       3. triggering - effector: every lookup to DEP.x invokes a call
>>>>          somewhere eg $brooklyn:entity(SRC).effector(...)
>>>>      A widespread use of (3) scares me [Alex] and it's worth avoiding
>>>>      this if at all possible. it also means lookups aren't idempotent
>>>>      (which is why the SideEffecting marker is introduced here, but it
>>>>      isn't going to work.
>>>>      could your [use-case] be solved another way, if not with waiting on
>>>>      a sensor, by the config pointing at the source entity rather than
>>>>      the key value itself, and whenever it is accessed there is code
>>>>      which invokes the effector to get the key on that source entity?
>>>> ---
>>>> I believe the original use-case that motivated this was setting up a
>>>> docker host, with certificates dynamically generated by a CA Server
>>>> (Certificate Authority).
>>>> The blueprint has a CA Server entity and several Docker Host entities.
>> For
>>>> setting up each Docker Host, we want a new certifiacte that is signed by
>>>> the CA. We want to put the certificate files onto the Docker Host (so
>> that
>>>> the Docker Engine is correctly configured for TLS).
>>>> There is an effector on the CA entity, to send it a Certificate Signing
>>>> Request (CSR), and thus to get back a new certificate.
>>>> One solution in pure-yaml blueprints (simplified slightly for clarity in
>>>> this discussion) would be to have a "certificate" config key on the
>> Docker
>>>> Host entity. This would be set to a value like:
>>>>      brooklyn.config:
>>>>         certificateData:
>>>>      $brooklyn:entity("ca").effector("requestCertificate"):
>>>>             args:
>>>>               ip: $brooklyn:config("host.address")
>>>> Part of the setup script would use this config key, and create a file
>>>> using its value.
>>>> When the config key was evaluated for the first time, it would execute
>> the
>>>> effector and thus get a new certificate. Subsequent lookups of the
>> config
>>>> key would use the same value (rather than invoking the effector multiple
>>>> times).
>>>> Note the significant difference compared to Alex's summary, where Alex
>>>> suggested the effector would be invoked every time the config key value
>>> was
>>>> retrieved.
>>>> ===
>>>> Below are some alternative ways to solve the above use-case. I don't
>> want
>>>> us to get too distracted in this discussion of "yaml DSL for invoking
>>>> effectors". However, if we reach agreement that one of these alternative
>>> is
>>>> better then we can ignore the use-case that I've described above.
>>>> _*Resort to Java*_
>>>> We could resort to writing some Java code (e.g. write an
>>>> "EntityInitializer" that called the requestCertificate effector, and set
>>>> the result as a sensor; this could be added to the Docker Host entity.
>> The
>>>> rest of the Docker Host blueprint would use attributeWhenReady on the
>>>> "certificateData" sensor.
>>>> There could be a generic EntityInitializer for invoking a given effector
>>>> on a given entity, and setting a sensor with the result.
>>>> _*Defining an Effector as a Sequence of Tasks*_
>>>> Longer term, we could add YAML support for describing a sequence of
>> tasks.
>>>> The basic Docker Host entity would be extended so that its "start"
>>> effector
>>>> first invoked a task, which would call the "requestCertificate" effector
>>> on
>>>> the CA (and probably set the result as a sensor or config key).

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message