Re: Dynamically registering reactive handlers at runtime

2016-02-18 Thread Stuart Bishop
> The possible values for package-names are not known during build time. We do
> know that _all_ queued packages have to be installed. Would it be possible
> to have an `apt.installed.all` state?

@when_not('apt.queued_installs') tells you this.

@when_not('packages_queued')
def queue_package_installations():
apt.queue_install(config()['packages'].split())
reactive.set_state('packages_queued')

@when('packages_queued')
@when_not('apt.queued_installs')
def do_setup():
# packages installed. Lets do this
[...]


If you can calculate the packages at import time, you could also do this:

package_states = ['apt.installed.{}'.format(p) for p in
config()['packages'].split()]

@when(*package_states)
def do_setup():
# Packages installed. Lets do this
[...]


And for more potential solutions, the documentation for the apt layer
has been updated which states you can call charms.apt.install_queued()
yourself to install queued packages right now. It does nothing if
nothing is queued, so you could just call it at the start of your
handler instead of waiting on an apt.installed.* state at all.

-- 
Stuart Bishop 

-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Dynamically registering reactive handlers at runtime

2016-02-18 Thread Merlijn Sebrechts
Thanks Stuart, I'm learning a lot of cool things about Python :)

I think charms.apt.install_queued() is what we'll use for the moment.

2016-02-18 18:04 GMT+01:00 Stuart Bishop :

> On 18 February 2016 at 17:15, Merlijn Sebrechts
>  wrote:
>
> > The possible values for package-names are not known during build time.
> We do
> > know that _all_ queued packages have to be installed. Would it be
> possible
> > to have an `apt.installed.all` state?
>
> @when_not('apt.queued_installs') tells you this.
>
> @when_not('packages_queued')
> def queue_package_installations():
> apt.queue_install(config()['packages'].split())
> reactive.set_state('packages_queued')
>
> @when('packages_queued')
> @when_not('apt.queued_installs')
> def do_setup():
> # packages installed. Lets do this
> [...]
>
>
> If you can calculate the packages at import time, you could also do this:
>
> package_states = ['apt.installed.{}'.format(p) for p in
> config()['packages'].split()]
>
> @when(*package_states)
> def do_setup():
> # Packages installed. Lets do this
> [...]
>
>
> And for more potential solutions, the documentation for the apt layer
> has been updated which states you can call charms.apt.install_queued()
> yourself to install queued packages right now. It does nothing if
> nothing is queued, so you could just call it at the start of your
> handler instead of waiting on an apt.installed.* state at all.
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Dynamically registering reactive handlers at runtime

2016-02-18 Thread Alex Kavanagh
Hi Merlijn

On Thu, Feb 18, 2016 at 10:15 AM, Merlijn Sebrechts <
merlijn.sebrec...@gmail.com> wrote:

>
> Thank you for your response, we did not realize this was the case, this
> might come in handy!
>
> Now to get some clarification: If we have the following code:
>
> if some-condition:
> @when(...)
> def some_function(...):
> ...
>
> and `some-condition` changes after the initial registration of handlers.
> Will `some_function` be registered, or will this only happen during the
> next hook run?
>

A new process is invoked for each 'run' of a hook, and so from the
perspective of the Python script/program it is starting anew each time for
each hook invocation (i.e. there is no 'server' handling hooks).  Thus the
@when(...) are registered every time a hook is called.

So, if you register them dynamically, then they could be different during
each hook invocation.  Whether this is a good idea is debatable as the
hooks registered would be determined by the state of the system as a whole
which might make it tricky to debug, test, and reason about.


>
> The possible values for package-names are not known during build time. We
> do know that _all_ queued packages have to be installed. Would it be
> possible to have an `apt.installed.all` state?
>

Well, your own script sets the states, so yes; but I don't know enough
about your use case to advise on that - I was more commenting on what's
possible in Python.

Cheers
Alex.


-- 
Alex Kavanagh - Software Engineer
Cloud Dev Ops - Solutions & Product Engineering - Canonical Ltd
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Dynamically registering reactive handlers at runtime

2016-02-18 Thread Merlijn Sebrechts
Hi Alex


Thank you for your response, we did not realize this was the case, this
might come in handy!

Now to get some clarification: If we have the following code:

if some-condition:
@when(...)
def some_function(...):
...

and `some-condition` changes after the initial registration of handlers.
Will `some_function` be registered, or will this only happen during the
next hook run?

The possible values for package-names are not known during build time. We
do know that _all_ queued packages have to be installed. Would it be
possible to have an `apt.installed.all` state?



Kind regards
Merlijn Sebrechts

2016-02-18 10:39 GMT+01:00 Alex Kavanagh :

>
>
> On Thu, Feb 18, 2016 at 7:23 AM, Stuart Bishop <
> stuart.bis...@canonical.com> wrote:
>
>> On 12 February 2016 at 22:55, Merlijn Sebrechts
>>  wrote:
>> > Hi all
>> >
>> >
>> > We have a layer that can install a number of different packages. It
>> decides
>> > at runtime which packages will be installed. This layer uses the `apt`
>> layer
>> > which sets a state `apt.installed.`.
>> >
>> > We want to react to this installed state, but we don't know what the
>> > packagename will be beforehand. This gets decided at runtime.
>> Therefore, we
>> > can't put it in a @when() decorator.
>> >
>> > Is there a way to dynamically register handlers at runtime?
>>
>
> From a Python perspective, there's nothing stopping you, at the top level
> in the file, or in a function, doing:
>
> if some-condition:
> @when(...)
> def some_function(...):
> ...
>
> i.e. decorators don't have to be at the top level in a module/file - they
> are essentially 'just' syntactic sugar for a function call on the defined
> function.
>
> @when(...)
> def something():
> 
>
> is conceptually equivalent to:
>
> def something():
> ...
>
> when(...)(something)
>
> However, I'd caution against dynamically defining the handlers, as it
> might make the program/script less easy to reason about, test and debug.
>
> I'm guessing that the possible values for packagename are known at build
> time, so could you not just either list them all with their appropriate
> handlers, or bundle them all into a single @when(...) if they share a
> common handler?
>
> e.g.
>
> @when('apt.installed.packagename1')
> def ...
>
> @when('apt.installed.packagename2')
> def ...
>
> and/or
>
> @when('apt.installed.packagename1', 'apt.installed.packagename2', ...)
> def ...
>
> Explicit tends to be more helpful than implicit.  Hope this is useful
> and/or helpful!
> Alex.
>
> --
> Alex Kavanagh - Software Engineer
> Cloud Dev Ops - Solutions & Product Engineering - Canonical Ltd
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Dynamically registering reactive handlers at runtime

2016-02-18 Thread Alex Kavanagh
On Thu, Feb 18, 2016 at 7:23 AM, Stuart Bishop 
wrote:

> On 12 February 2016 at 22:55, Merlijn Sebrechts
>  wrote:
> > Hi all
> >
> >
> > We have a layer that can install a number of different packages. It
> decides
> > at runtime which packages will be installed. This layer uses the `apt`
> layer
> > which sets a state `apt.installed.`.
> >
> > We want to react to this installed state, but we don't know what the
> > packagename will be beforehand. This gets decided at runtime. Therefore,
> we
> > can't put it in a @when() decorator.
> >
> > Is there a way to dynamically register handlers at runtime?
>

>From a Python perspective, there's nothing stopping you, at the top level
in the file, or in a function, doing:

if some-condition:
@when(...)
def some_function(...):
...

i.e. decorators don't have to be at the top level in a module/file - they
are essentially 'just' syntactic sugar for a function call on the defined
function.

@when(...)
def something():


is conceptually equivalent to:

def something():
...

when(...)(something)

However, I'd caution against dynamically defining the handlers, as it might
make the program/script less easy to reason about, test and debug.

I'm guessing that the possible values for packagename are known at build
time, so could you not just either list them all with their appropriate
handlers, or bundle them all into a single @when(...) if they share a
common handler?

e.g.

@when('apt.installed.packagename1')
def ...

@when('apt.installed.packagename2')
def ...

and/or

@when('apt.installed.packagename1', 'apt.installed.packagename2', ...)
def ...

Explicit tends to be more helpful than implicit.  Hope this is useful
and/or helpful!
Alex.

-- 
Alex Kavanagh - Software Engineer
Cloud Dev Ops - Solutions & Product Engineering - Canonical Ltd
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Dynamically registering reactive handlers at runtime

2016-02-17 Thread Stuart Bishop
On 12 February 2016 at 22:55, Merlijn Sebrechts
 wrote:
> Hi all
>
>
> We have a layer that can install a number of different packages. It decides
> at runtime which packages will be installed. This layer uses the `apt` layer
> which sets a state `apt.installed.`.
>
> We want to react to this installed state, but we don't know what the
> packagename will be beforehand. This gets decided at runtime. Therefore, we
> can't put it in a @when() decorator.
>
> Is there a way to dynamically register handlers at runtime?

Not with reactive as it stands, unless by 'at runtime' you mean 'at
import time'.

I previously patched @when_file_changed to accept callables, allowing
the filenames to be generated at run time. I imagine the same thing
would need to be done for the @when and @when_not decorators.

I'd experiment by creating your own decorator, and if it turns out to
be useful propose it as a charms.reactive update.

-- 
Stuart Bishop 

-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Dynamically registering reactive handlers at runtime

2016-02-12 Thread Merlijn Sebrechts
Hi all


We have a layer that can install a number of different packages. It decides
at runtime which packages will be installed. This layer uses the `apt`
layer which sets a state `apt.installed.`.

We want to react to this installed state, but we don't know what the
packagename will be beforehand. This gets decided at runtime. Therefore, we
can't put it in a @when() decorator.

Is there a way to dynamically register handlers at runtime?



Kind regards
Merlijn
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju