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

[builder] Change to facade #5036

Draft
wants to merge 33 commits into
base: master
Choose a base branch
from

Conversation

kriegfrj
Copy link
Contributor

@kriegfrj kriegfrj commented Jan 7, 2022

This is an early-access PR for those interested in how it's coming together.

The code is in obvious need of some tidy-ups. But I think I have reached a point where I can start trying to implement some regression tests. Before I ploughed ahead too much further I wanted to give the opportunity for some feedback on the direction/architecture.

Key features:

  • I have added whiteboard behaviour for IResourceChangeListeners. You don't have to worry about registering/unregistering your listeners as DS will do it for you courtesy of the ResourceWhiteboard component. Just register a service/component that implements IResourceChangeListener and it will automatically receive resource change event notifications.
  • Validators and ProjectValidators are now exclusively service-driven (part of fix for [arch] Deprecate custom extension points for use in Bndtools #5005).
  • BndtoolsBuilder is now a dynamically-restartable component, using an adapted facade pattern. Because the base class for builders is an abstract class rather than an interface, this required a slightly different approach, but it seems to be working. (Closes [builder] Convert Bndtools builder to a facade pattern #5004).
  • IStartupParticipant is superseded by a pattern of using DS component activation for start/stop (part of fix for [arch] Deprecate custom extension points for use in Bndtools #5005).
  • Central is now itself a DS component. It also automatically triggers background initialization and registration of the Workspace object as a service (whereas before it would happen when the first client tried to access it). This makes it easy for components that depend on Central being initialized to simply add it as a static reference.

There is still further simplification to be made by converting other pieces to DS components (eg, BndPreferences). But I think this is a good point to stop and add regression tests that will then make further such refactoring safer.

@kriegfrj kriegfrj marked this pull request as draft January 7, 2022 14:01
@kriegfrj kriegfrj force-pushed the builder-facade-with-central branch 4 times, most recently from 0704c84 to abaf55b Compare January 16, 2022 12:59
@kriegfrj kriegfrj marked this pull request as ready for review January 16, 2022 13:38
@kriegfrj
Copy link
Contributor Author

Still a little bit of work to do but I think it is mostly working and probably at a good point where it could benefit from a review.

@kriegfrj kriegfrj force-pushed the builder-facade-with-central branch 3 times, most recently from 1ef3215 to 7d512cc Compare January 17, 2022 04:44
@kriegfrj
Copy link
Contributor Author

Think I've done most of the tidying-up now. Let me have it, @bjhargrave! 😄

Copy link
Member

@bjhargrave bjhargrave left a comment

Choose a reason for hiding this comment

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

Wow, what a massive piece of work!

I, of course, have some comments :-)

bndtools.core/src/bndtools/central/Central.java Outdated Show resolved Hide resolved
bndtools.builder/bnd.bnd Outdated Show resolved Hide resolved
bndtools.api/src/org/bndtools/facade/ExtensionFacade.java Outdated Show resolved Hide resolved
bndtools.core/bnd.bnd Outdated Show resolved Hide resolved
bndtools.core/src/bndtools/central/ResourceWhiteboard.java Outdated Show resolved Hide resolved
bndtools.core/src/bndtools/central/QueryWhiteboard.java Outdated Show resolved Hide resolved
@kriegfrj
Copy link
Contributor Author

Wow, what a massive piece of work!

Well, when you take out moved files and updates from Eclipse automated refactoring, it's probably not as big as it looks at first glance. 😄

I, of course, have some comments :-)

I was hoping (and expecting) as much! 😄

@djencks
Copy link
Contributor

djencks commented Jan 19, 2022 via email

@kriegfrj
Copy link
Contributor Author

Could you describe the problem leading to NPEs when using DS in more detail? From the description below it doesn’t make any sense to me that this could be happening. Thanks David Jencks

Sorry, it wasn't a generic DS problem but a problem with my specific implementation.

The original implementation simply called workspace.add/RemoveResourceChangeListener() as was appropriate. The problem was that the component wasn't fully activated (workspace was still null) when the first ResourceChangeListener services started getting implemented, which is why my implementation was causing an NPE. I couldn't see an easy way to fix that without buffering the resource listeners as they were registered and then registering them once the component was fully activated, which is why I employed a ServiceTracker to do that for me.

@djencks
Copy link
Contributor

djencks commented Jan 19, 2022 via email

@kriegfrj
Copy link
Contributor Author

New push incorporates most of the changes above. Waiting for further discussion on the remainder.

@kriegfrj
Copy link
Contributor Author

Latest push incorporates the last suggestions.

I think this still needs some more testing before we merge though - in particular, I think there are issues with the Java search and seems occasional startup issues where the builder is not ready in time.

@bjhargrave
Copy link
Member

I think we should defer merging this until after 6.2.0 is released. We plan 6.2.0-RC1 for Feb 4.

@kriegfrj
Copy link
Contributor Author

I think we should defer merging this until after 6.2.0 is released. We plan 6.2.0-RC1 for Feb 4.

I agree. Though I was hoping at least a fix for #3175 might be able to be cherŕypicked.

@kriegfrj
Copy link
Contributor Author

I think we should defer merging this until after 6.2.0 is released. We plan 6.2.0-RC1 for Feb 4.

I agree. Though I was hoping at least a fix for #3175 might be able to be cherŕypicked.

On second thoughts, probably better to defer that fix too to give the early adopters more time to test it out.

@bjhargrave bjhargrave added this to the 6.3 milestone Jan 28, 2022
@kriegfrj
Copy link
Contributor Author

kriegfrj commented Feb 8, 2022

Latest push incorporates the last suggestions.

I think this still needs some more testing before we merge though - in particular, I think there are issues with the Java search and seems occasional startup issues where the builder is not ready in time.

For posterity:

  • I haven't invested much time in fixing the Java search issues, as I'm actually hoping that [Feature] Smarter builder dependency checking #3175 will make the special Java search filter redundant.
  • I think I have fixed many startup timing issues by changing calls to tracker.getService() with tracker.waitForService(10000) where appropriate.

Temporarily turn on debugging for review in case some CI failures
pop up that don't happen on local box. Expect that this commit will
be removed from the final PR.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Was previously dependent on Bnd workspace only.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Also fixes a potential race condition (albeit rare) in the dynamic
reference provider where the isDefaultWorkspace() call was called
outside of the read lock, so there was potential for its default
status to change before the information could be retrieved.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Because it is an abstract class rather than an interface the regular
ExtensionFacade approach will not work.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Since the upgrade to Eclipse baseline of 2022-09, it seems that Eclipse
registers the workspace as an IWorkspace object. An exception stacktrace
even recommends depending on this using DS or similar instead of using the
static method ResourcePlugin.getWorkspace(). Adding this dependency fixes
some runtime startup ordering problems.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Hopefully the fixes to startup ordering in bndtools#5036 have fixed the flakiness
issues.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
The BndContainerInitializer incorrectly depended on Central instead of ICentral.
The Central component itself depended on the (Eclipse) Workspace, this has now
been changed to depend on the Workbench so that Central is not created too early,
which was causing a deadlock in the integration tests.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Hopefully this will fix a startup issue.

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
…tartup

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Specifying an explicit EE requires that EE to be registered in the workspace.
That is too hard...

Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>
Signed-off-by: Fr Jeremy Krieg <fr.jkrieg@greekwelfaresa.org.au>

void removeModelListener(ModelListener m);

void close();
Copy link
Contributor

@laeubi laeubi Nov 14, 2023

Choose a reason for hiding this comment

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

Is it really whise to have close on a service interface? How one would ever open the workspace again? what happens if one is currently workin on it and it gets closed concurrently...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you're probably right. In fact, I just did some code searches and found that the original Central.close() is not even called anywhere from within Bndtools, so I think we can safely remove it.


void changed(Project model);

void addModelListener(ModelListener m);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe model listener can better use the whiteboardpattern instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree 100%.

This was more about me trying to limit the scope of my PR which had already grown into a behemoth. This part of the code is not particularly well tested in CI (which is to say, not really tested at all!) and so I had a fear that something might break. So the goal was to make the minimal changes I needed in this PR to get the automated testing working reliably, and also so that it could get merged so that it could be subjected to some real-world testing by us on the bleeding edge. Then I could then proceed with additional refactorings (like this) with a little bit more confidence that I haven't broken anything in a subtle or fundamental way. I can foresee this interface evolving significantly as we start to leverage the power of a more component-driven approach.

Copy link
Contributor

Choose a reason for hiding this comment

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

It dosen't hurt to have those though...

@ProviderType
public interface ICentral {

Project getModel(IJavaProject project);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Project getModel(IJavaProject project);
Optional<Project> getModel(IProject project);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Our codebase hasn't made heavy use of the Optional pattern. But I suppose we probably should...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just noticed that this was also a change of the argument type from IJavaProject to IProject. I'm curious as to the reasoning? Every Bnd project is also a Java project.

Copy link
Contributor

@laeubi laeubi Nov 15, 2023

Choose a reason for hiding this comment

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

It is easy to get from IJavaProject > IProject but the other is not that easy (and better handled on a central 😛 place), also as it is maybe now the case who knows what the future brings?
So usually IProject is much more comfortable to use from api user point of view as you almost ever have one at hand.

Copy link
Member

Choose a reason for hiding this comment

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

Our codebase hasn't made heavy use of the Optional pattern. But I suppose we probably should...

I've been using Result more and more. This has all the methods of Optional but

  • it allows to carry a message when it fails,
  • easy message construction with improved String.format,
  • It allows lambdas that throw exceptions.

The idea is derived from Rust.

@kriegfrj
Copy link
Contributor Author

@laeubi , thank you so much for reviewing and your suggested changes! I have made some counter-comments above.

@pkriens
Copy link
Member

pkriens commented Nov 16, 2023

After doing a lot of thinking and can't getting it out of my head, I've prepared a general solution for the facades that would be useful in Extension Points.

See #5900

@kriegfrj kriegfrj mentioned this pull request Nov 22, 2023
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.

[builder] Convert Bndtools builder to a facade pattern
7 participants