Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wait-for] lambda support #12196

Merged
merged 9 commits into from
Nov 2, 2020

Conversation

SimonRichardson
Copy link
Member

@SimonRichardson SimonRichardson commented Oct 26, 2020

The following is a very initial idea for adding lambda support for
each query.

The idea is that we have a series of scopes that a scope can add to when
we enter a lambda. This is kind of like stack registers, but not as
complicated. The reason we don't need to implement stack registers is
that we're using the go runtime to do it for us, so we can piggyback
on to that without having to do any of the work!

Additional work to change Ord to Box. The Box value is more generalized
and not only talks about Ord syntax but syntax we need to do other
things like accessor values.

The idea of Box is the same as Java, except there is no bottom type.

Previously I was aiming to do applications.forEach, but actually that
introduces a lot of complexity into the query evaluator, so much so it
makes it really hard to understand. Instead, nothing can have a method
and we use high order functions to do this for us. We don't get the partial
application, but I don't think we need it tbh.

The code is rather simple, lift the sub-entity into its own scope and
then use that when we call the lambda. We get a lot of things for free
and it works surprisingly well.

The accessor is identical to the infix in terms of using the order
precedence, but we have a new AST type so that the query evaluator
doesn't become a mess.

juju-wait-for model default --query='forEach(applications, app => app.status == "active")'

As there is no order in the forEach, it might be wise to order them to
get some valid expected behavior.

QA steps

juju-wait-for model default --query='forEach(applications, app => app.status == "active")'

@SimonRichardson SimonRichardson marked this pull request as ready for review October 27, 2020 17:05
@SimonRichardson SimonRichardson changed the title Wait for lambda support [wait-for] lambda support Oct 29, 2020
The following is a very initial idea for adding lambda support to for
each queries. It has not been generalised yet, but essentially it should
be doable.

The idea is that we have a series of scopes that a scope can add to when
we enter a lambda. This is kind of like stack registers, but not as
complicated. The reason we don't need to implement stack registers is
because we're using the go runtime to do it for us, so we can piggy back
on to that without having to do any of the work!

Additional work to change Ord to Box. The Box value is more generalised
and not only talks about Ord syntax, but syntax we need to do other
things like accessor values.

The idea of Box is the same as Java, except there is no bottom type.
Previously I was aiming to do `applications.forEach`, but actually that
introduces a lot of complexity in to the query evaluator, so much so it
makes it really hard to understand. Instead nothing can have a method
and we use high order functions to do this for us. We don't get partial
application, but I don't think we need it tbh.

The code is rather simple, lift the sub entity into it's own scope and
then use that when we call the lambda. We get a lot of things for free
and it works suprisingly well.

The accessor is identical to the infix in terms of using the order
precedence, but we have a new AST type so that the query evaluator
doesn't become a mess.

    juju-wait-for model default --query='forEach(applications, app =>
    app.status == "active")'

As there is no order in the forEach, it might be wise to order them to
get some valid expected behaviour.
The generic scope is no longer required.
It is now possible to do...

    juju-wait-for model default --query='status == "available" &&
    forEach(applications, app => app.status == "active")'

Previously we ended up with app.status being unset
The foreach abstraction is more generalised so we don't pollute the box
type. This makes it much easier to implement new box types without
having to have empty foreach methods.

Additionally added machines to the model.
The following adds more test cases to the query tests
The item intends to order some of the for each calls to make it a lot
more predictable.
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I create the model, run the query, then deploy ubuntu, the query doesn't return even when it becomes active.

cmd/plugins/juju-wait-for/strategy.go Outdated Show resolved Hide resolved
The order of AllWatcher deltas might not be in an expected order, to
which the derived status of the application might not have been
processed if the unit delta hasn't arrived.

To fix this cache the model and force the revaluation every time, which
is worse for performance, but because it's on the client side, it
shouldn't matter too much. Yet still this is another time that the
application status change has forced client side changes.
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well now.

@SimonRichardson
Copy link
Member Author

$$merge$$

@jujubot jujubot merged commit dde11ad into juju:develop Nov 2, 2020
@SimonRichardson SimonRichardson deleted the wait-for-lambda-support branch November 2, 2020 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants