Skip to content

add delegate to track events from the dependency resolver #3420

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

Merged
merged 2 commits into from
Apr 22, 2021

Conversation

tomerd
Copy link
Contributor

@tomerd tomerd commented Apr 21, 2021

motivation:

  • significant part of package resolution can be spent in the dependency resolver which does not emit events we can use to tell the user what is happening
  • a follow up PR would use these new events to emit information when package dependencies are resolved, e.g when running swift package update

chnages:

  • define DependencyResolverDelegate
  • replace logging in PubgrubDependencyResolver with calling the relevant delegate methods
  • add TracingDependencyResolverDelegate which back-fills the existing logging behavior in PubgrubDependencyResolver
  • adjust call-sites

@tomerd tomerd marked this pull request as draft April 21, 2021 00:47
@tomerd
Copy link
Contributor Author

tomerd commented Apr 21, 2021

@neonichu @abertelrud looking for early feedback on the approach and open questions, so we can finalize the feature


public protocol DependencyResolverDelegate {
func willResolve(term: Term)
func didResolve(term: Term, version: Version)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

^^ we need for sure

func satisfied(term: Term, by: Assignment, incompatibility: Incompatibility)
func partiallySatisfied(term: Term, by: Assignment, incompatibility: Incompatibility, difference: Term)
func failedToResolve(incompatibility: Incompatibility)
func computed(bindings: [DependencyResolver.Binding])
Copy link
Contributor Author

@tomerd tomerd Apr 21, 2021

Choose a reason for hiding this comment

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

^^ are more questionable and mirror the current logging behavior of pubgrub resolver

@neonichu
Copy link
Contributor

neonichu commented Apr 21, 2021

I think having a delegate that's 1:1 with the only current resolver makes sense to me, we can choose to not emit logs for every callback if we want to. I don't think we will know enough to have a differently shaped delegate until we would actually have more than one resolver implementation.

@abertelrud
Copy link
Contributor

I think having a delegate that's 1:1 with the only current resolver makes sense to me, we can choose to not emit logs for every callback if we want to. I don't think we will know enough to have a differently shaped delegate until we would actually have more than one resolver implementation.

100%. As Boris says, the callbacks should reflect what's actually happening. Individual delegates can then easily choose to ignore some of them, as long as they are all optional.

Copy link
Contributor

@abertelrud abertelrud left a comment

Choose a reason for hiding this comment

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

This looks great! I know it's a WIP but already looks very useful.

@abertelrud
Copy link
Contributor

I think having a delegate that's 1:1 with the only current resolver makes sense to me, we can choose to not emit logs for every callback if we want to. I don't think we will know enough to have a differently shaped delegate until we would actually have more than one resolver implementation.

100%. As Boris says, the callbacks should reflect what's actually happening. Individual delegates can then easily choose to ignore some of them, as long as they are all optional.

I think I want to modulate this statement ("all optional"): since the delegate itself is optional, it might make sense to define the "major" events that the delegate just has to implement, and then maybe some of the minor ones could be optional (have default implementations that don't do anything). Or should they all be optional for consistency, especially since any new ones that get added later will have to be optional for compatibility reasons (until libSwiftPM is properly versioned). WDYT?

@tomerd
Copy link
Contributor Author

tomerd commented Apr 21, 2021

I think I want to modulate this statement ("all optional"): since the delegate itself is optional, it might make sense to define the "major" events that the delegate just has to implement, and then maybe some of the minor ones could be optional (have default implementations that don't do anything). Or should they all be optional for consistency, especially since any new ones that get added later will have to be optional for compatibility reasons (until libSwiftPM is properly versioned). WDYT?

I actually dislike the current pattern in SwiftPM where we have empty implementation for delegates to make them seem optional. sure, it makes life easier for the caller when they first add a delegate but it makes it very difficult to properly evolve the delegate API inc. deprecations as the default empty ones hide the fact that that API changed from the caller making these into runtime issues. in other words, I'd like to see us factor out all the default empty delegate extensions so that the caller can decide explicitly what to ignore and be notified when we deprecate delegate APIs.

tomerd added 2 commits April 21, 2021 13:38
…solver

motivation:
* significant part of pacakge resolution is spent in the dependency resolver which does not emit events we can use to tell the user what is happening
* a follow up PR would use these new events to emit inforamtion when package depedencies are resolved, e.g when running swift package update

chnages:
* define DependencyResolverDelegate
* replace logging in PubgrubDependencyResolver with calling the relevant delegate methods
* add TracingDependencyResolverDelegate which back-fills the existing logging behavior in PubgrubDependencyResolver
* adjust call-sites

open issues:
* is this the right API shape? the delegate methods are 1:1 mapping to PubgrubDependencyResolver logging which may or may not be the right API
* add tests once API is stable
@tomerd tomerd force-pushed the feature/resolver-delegate branch from 1628832 to 42e0e92 Compare April 21, 2021 22:43
@tomerd tomerd changed the title [WIP] add delegate to track events from the dependency resolver add delegate to track events from the dependency resolver Apr 21, 2021
@tomerd tomerd marked this pull request as ready for review April 21, 2021 22:45
@tomerd
Copy link
Contributor Author

tomerd commented Apr 21, 2021

@swift-ci please smoke test

@tomerd tomerd added the ready Author believes the PR is ready to be merged & any feedback has been addressed label Apr 21, 2021
@abertelrud
Copy link
Contributor

I think I want to modulate this statement ("all optional"): since the delegate itself is optional, it might make sense to define the "major" events that the delegate just has to implement, and then maybe some of the minor ones could be optional (have default implementations that don't do anything). Or should they all be optional for consistency, especially since any new ones that get added later will have to be optional for compatibility reasons (until libSwiftPM is properly versioned). WDYT?

I actually dislike the current pattern in SwiftPM where we have empty implementation for delegates to make them seem optional. sure, it makes life easier for the caller when they first add a delegate but it makes it very difficult to properly evolve the delegate API inc. deprecations as the default empty ones hide the fact that that API changed from the caller making these into runtime issues. in other words, I'd like to see us factor out all the default empty delegate extensions so that the caller can decide explicitly what to ignore and be notified when we deprecate delegate APIs.

That makes sense. That will be easier to do once we adopt semantic versioning. At least some of the empty delegates now are to avoid breaking clients, I think.

@abertelrud
Copy link
Contributor

This looks great to me.

@abertelrud abertelrud self-requested a review April 22, 2021 20:17
@tomerd tomerd merged commit 3b4f86e into swiftlang:main Apr 22, 2021
tomerd added a commit to tomerd/swift-package-manager that referenced this pull request Apr 22, 2021
…3420)

motivation:
* significant part of pacakge resolution is spent in the dependency resolver which does not emit events we can use to tell the user what is happening
* a follow up PR would use these new events to emit inforamtion when package depedencies are resolved, e.g when running swift package update

chnages:
* define DependencyResolverDelegate
* replace logging in PubgrubDependencyResolver with calling the relevant delegate methods
* add TracingDependencyResolverDelegate which back-fills the existing logging behavior in PubgrubDependencyResolver
* adjust call-sites
tomerd added a commit that referenced this pull request Apr 23, 2021
)

motivation:
* significant part of pacakge resolution is spent in the dependency resolver which does not emit events we can use to tell the user what is happening
* a follow up PR would use these new events to emit inforamtion when package depedencies are resolved, e.g when running swift package update

chnages:
* define DependencyResolverDelegate
* replace logging in PubgrubDependencyResolver with calling the relevant delegate methods
* add TracingDependencyResolverDelegate which back-fills the existing logging behavior in PubgrubDependencyResolver
* adjust call-sites
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready Author believes the PR is ready to be merged & any feedback has been addressed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants