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

feat(overlord): allow adding external managers #273

Merged
merged 20 commits into from
Aug 25, 2023

Conversation

paul-rodriguez
Copy link
Contributor

@paul-rodriguez paul-rodriguez commented Aug 8, 2023

This change enables an external application importing Pebble to extend the overlord functionality by adding additional managers.

Example overlord extension:

package ovldext

type OverlordExtension struct {
	fooManager *foostate.Manager
	barManager *barstate.Manager
}

func New() *OverlordExtension {
    return &OverlordExtension{}
}

func (oe *OverlordExtension) ExtraManagers(o *Overlord) ([]overlord.StateManager, error) {
    oe.fooManager, err := foostate.NewManager(o.State(), o.TaskRunner())
    if err != nil {
        return nil, err
    }
    oe.barManager, err = barstate.NewManager(o.State(), o.TaskRunner())
    if err != nil {
        return nil, err
    }
    return []overlord.StateManager{oe.fooManager, oe.barManager}, nil
}

func (oe *OverlordExtension) FooManager() *foostate.Manager { return oe.fooManager }

func (oe *OverlordExtension) BarManager() *barstate.Manager { return oe.barManager }

func Extension(o *overlord.Overlord) *OverlordExtension {
	return o.Extension().(*OverlordExtension)
}

Example startup code:

    dopts := daemon.Options{
        Dir:        pebbleDir,
        SocketPath: socketPath,

        // Supply overlord extension
        OverlordExtension: ovldext.New()            
    }
    
    d, err := daemon.New(&dopts)
    if err != nil {
        return err
    }

External HTTP request handler example:

    :  
    // We can now get access to the overlord
    o := d.Overlord()
    
    // Get access to the custom state manager to perform the HTTP request
    fooManager := ovldext.Extension(o).FooManager()
    :

Copy link
Contributor

@flotter flotter left a comment

Choose a reason for hiding this comment

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

Some brainstorming ideas for discussion.

internals/overlord/stateengine.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/daemon/daemon.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@anpep anpep left a comment

Choose a reason for hiding this comment

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

I don't think the approach taken here is suitable for a public-facing API.

A simpler approach I suggest: having separate func New(...) (*Overlord, error) and func (*Overlord) Init() error functions, then have a func (*Overlord) AddManager(StateManager) error that we can simply call before o.Init().

What do you think?

@paul-rodriguez
Copy link
Contributor Author

I don't think the approach taken here is suitable for a public-facing API.

A simpler approach I suggest: having separate func New(...) (*Overlord, error) and func (*Overlord) Init() error functions, then have a func (*Overlord) AddManager(StateManager) error that we can simply call before o.Init().

What do you think?

I don't like letting the user of that code be bitten by forgetting Init or calling AddManager after Init. Right now Overlord is more or less RAII, let's keep it that way if possible.

Here the only purpose of Init would be to ensure the TaskRunner is the last manager. With the changes I made to the StateEngine, Init is not necessary. You can AddManager in cmd_run as Fred suggested.

This commit introduces StateEngine.SetTaskRunner and therefore relaxes
the constraint on the ordering of the managers in the StateEngine.
This change has made the inited field of Overlord obsolete: there is
no reason to guard against adding managers after Overlord.New anymore.
So the inited field has been removed too.

In turn, the relaxing of the ordering allows sister projects to add
managers to the Overlord. The Overlord of a given Daemon can now be
reached using a method of Daemon, so the sister project can use this
functionality on their own Daemon.
@paul-rodriguez paul-rodriguez marked this pull request as ready for review August 21, 2023 10:40
@flotter flotter changed the title overlord: allow adding custom managers feat(overlord): allow adding custom managers Aug 21, 2023
@flotter flotter changed the title feat(overlord): allow adding custom managers feat(overlord): allow extending overlord with custom managers Aug 21, 2023
Copy link
Contributor

@flotter flotter left a comment

Choose a reason for hiding this comment

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

There appears to be a linter failure in one of the tests.

Copy link
Collaborator

@anpep anpep left a comment

Choose a reason for hiding this comment

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

Excellent work on this @paul-rodriguez!

.github/workflows/lint.yml Outdated Show resolved Hide resolved
Copy link
Contributor

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

It's a bit awkward, but I understand why the task runner is special, and this seems reasonable to me -- it's definitely nice and simple!

@flotter flotter changed the title feat(overlord): allow extending overlord with custom managers feat(overlord): allow extending overlord with external managers Aug 22, 2023
.github/workflows/lint.yml Outdated Show resolved Hide resolved
@flotter flotter changed the title feat(overlord): allow extending overlord with external managers feat(overlord): allow adding external managers Aug 22, 2023
Copy link
Contributor

@niemeyer niemeyer left a comment

Choose a reason for hiding this comment

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

Just for my own tracking, we've discussed this and the approach here is not going in a good direction as it's misusing the abstractions we have. Let's please get together and figure a better way to do this.

Copy link
Contributor

@flotter flotter left a comment

Choose a reason for hiding this comment

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

Looks great Paul. I think this is perfect for a first round of reviews, including a proposal discussion with Gustavo. I've taken the liberty to update the example in the PR description for a quick highlight of this scheme for understanding the proposal.

internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
@flotter
Copy link
Contributor

flotter commented Aug 23, 2023

Current status: Further discussions required. Current design unlikely to progress in its current form.

@flotter flotter requested a review from benhoyt August 24, 2023 07:32
Copy link
Contributor

@flotter flotter left a comment

Choose a reason for hiding this comment

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

Great! Added a few nitty and minor comments, as I think we may have time to do a detailed code review during our next meeting.

internals/daemon/daemon.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
@flotter flotter self-requested a review August 24, 2023 08:53
Copy link
Contributor

@flotter flotter left a comment

Choose a reason for hiding this comment

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

Great work Paul. Looks super nice.

Regarding the PR description example, feel free to remote it or change it if you want. I find it essential assisting reviewers get the complete picture for things talking about some hypothetical external use-case (especially when discussing in person), but do not feel like we have to keep it there, or that version of it.

internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
@flotter flotter mentioned this pull request Aug 24, 2023
Copy link
Contributor

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

This seems reasonable to me. Couple of comments about comments.

internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/daemon/daemon_test.go Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@anpep anpep left a comment

Choose a reason for hiding this comment

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

Stellar work on this Paul, thank you!

@flotter flotter added the High Priority Look at me first label Aug 25, 2023
Copy link
Contributor

@niemeyer niemeyer left a comment

Choose a reason for hiding this comment

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

Thank you, that turned out well. Only documentation tuning suggested below.

internals/overlord/overlord.go Outdated Show resolved Hide resolved
internals/overlord/overlord.go Outdated Show resolved Hide resolved
@flotter
Copy link
Contributor

flotter commented Aug 25, 2023

Last two corrections added. Approved by Gustavo. Merging.

@flotter flotter merged commit 76414a1 into canonical:master Aug 25, 2023
13 checks passed
@benhoyt benhoyt mentioned this pull request Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
High Priority Look at me first
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants