Skip to content

Conversation

@olamy
Copy link
Member

@olamy olamy commented Jun 17, 2021

  • start work on get rid of guava...
  • remove most of the guava usage

return false;
}
if (o == null || Primitives.isWrapperType(o.getClass()) || o.getClass().isEnum()) {
if (o == null || o.getClass().isPrimitive() || o.getClass().isEnum()) {
Copy link
Member

Choose a reason for hiding this comment

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

I think these have different meanings. The old Guava code is true for boxed types like Integer or Double, whereas the new code is true for primitive types like int or double.

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch

return Collections.emptyMap();
}
HashMap<String, Object> filteredArguments = Maps.newHashMapWithExpectedSize(internalArgs.size());
HashMap<String, Object> filteredArguments = new HashMap(internalArgs.size());
Copy link
Member

Choose a reason for hiding this comment

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

Note that there is a subtle difference between these, see the discussion of loadFactor in the HashMap documentation.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I know but looking at the context. It probably doesn't hurt...

        HashMap<String, Object> filteredArguments = new HashMap(internalArgs.size());
        for (Map.Entry<String, Object> entry : internalArgs.entrySet()) {
            if (entry.getValue() != null && !(entry.getValue() instanceof NotStoredReason)) {
                // TODO this is incorrect: value could be a Map/List with some nested entries that are NotStoredReason
                filteredArguments.put(entry.getKey(), entry.getValue());
            }
        }

If 25% of the internalArgs Map is filtered by the if condition this optimisation with size/loadfactor doesn't make any sense.
and by the way looking at the rest of the code this Map is only read.
I might more using something such?:

        Map<String, Object>  filteredArguments = internalArgs.entrySet().stream()
            .filter(entry -> entry.getValue() != null && !(entry.getValue() instanceof NotStoredReason))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Comment on lines 251 to +264
public FlowNode findFirstMatch(@CheckForNull Collection<FlowNode> heads,
@CheckForNull Collection<FlowNode> blackListNodes,
Predicate<FlowNode> matchCondition) {
@CheckForNull Collection<FlowNode> blackListNodes,
Predicate<FlowNode> matchCondition) {
Copy link
Member

@dwnusbaum dwnusbaum Jun 17, 2021

Choose a reason for hiding this comment

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

FWIW, I think changing signatures like this from Guava's Predicate to Java 8's Predicate will be a breaking change for some plugins, so you might need to introduce the new signature while keeping the old one around for a few releases to give you time to update other plugins.

Copy link
Member Author

@olamy olamy Jun 18, 2021

Choose a reason for hiding this comment

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

Yup agree, it's a bit too agressive change... Even if I checked with usage-in-plugins and there is not so much usage of that.
Interesting if the code is using only lambda maybe is not a problem (at least at compile time). But yup will not work at runtime :)
but yeah might be better to keep both (but that's a lot... especially a lot are already marked deprecated..)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think a lot of cases would be fine, but stuff like this along with callers like this would need to be updated.

olamy added 5 commits June 26, 2021 16:20
Signed-off-by: olivier lamy <olamy@apache.org>
Signed-off-by: olivier lamy <olamy@apache.org>
Signed-off-by: olivier lamy <olamy@apache.org>
Signed-off-by: Olivier Lamy <olamy@apache.org>
Signed-off-by: Olivier Lamy <olamy@apache.org>
@olamy olamy force-pushed the get-rid-of-guava branch from 8bd6539 to e153c46 Compare June 26, 2021 06:20
Signed-off-by: Olivier Lamy <olamy@apache.org>
@olamy olamy marked this pull request as ready for review June 26, 2021 06:24
Signed-off-by: Olivier Lamy <olamy@apache.org>
Copy link
Member

@dwnusbaum dwnusbaum left a comment

Choose a reason for hiding this comment

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

I think there is one change here that will break workflow-cps's tests in the PCT, and there are a few breaking changes that I think are probably safe in practice but that I would recommend either making them non-breaking or taking them a bit further to clean up a few more uses of Guava.

HashMap<String, Object> filteredArguments = Maps.newHashMapWithExpectedSize(internalArgs.size());
for (Map.Entry<String, Object> entry : internalArgs.entrySet()) {
if (entry.getValue() != null && !(entry.getValue() instanceof NotStoredReason)) {
// TODO this is incorrect: value could be a Map/List with some nested entries that are NotStoredReason
Copy link
Member

Choose a reason for hiding this comment

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

nit: I think this comment is still accurate, right? If so I would add it back to the new code.

return this;
}


Copy link
Member

Choose a reason for hiding this comment

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

Suggested change


/** Returns a filtered view of the iterator, which calls the iterator until matches are found */
@Nonnull
Filterator<T> filter(@Nonnull Predicate<T> matchCondition);
Copy link
Member

Choose a reason for hiding this comment

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

Adding a new non-default method to an interface is a breaking change for any classes that implement this interface, but from some quick searching I don't see any such implementations outside of this plugin.

I would either change this to a default method that delegates to the existing implementation to avoid breaking changes, or if you are fine with the breaking change as long as there is no impact, I would double-check for existing implementors with a tool like https://github.com/jenkins-infra/usage-in-plugins and then drop Guava entirely.

return (input != null && input.getAction(actionClass) != null);
}
};
public static Predicate<FlowNode> hasActionAsPredicate(@Nonnull final Class<? extends Action> actionClass) {
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, it's awkward to have to add a new method but we have no choice here. There will need to be quite a few downstream updates for this one: https://github.com/search?utf8=%E2%9C%93&q=user%3Ajenkinsci+hasActionPredicate&type=Code.

import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Predicate;
Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines +276 to +277
@Deprecated
public FlowNode findFirstMatch(@CheckForNull Collection<FlowNode> heads,
Copy link
Member

Choose a reason for hiding this comment

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

nit: For all of the methods you are deprecating, can you please add a Javadoc comment like @deprecated use {@link #newMethod(foo, Predicate)}?

import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.function.Predicate;
Copy link
Member

Choose a reason for hiding this comment

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

For whole-class changes like this, did you double-check to make sure that all of the methods in this class and other subclasses of AbstractFlowScanner that either return Predicate or use it for a parameter are overriding a method from AbstractScanner where you added a new overload using Guava's predicate to retain backwards compatibility?

For example, I think ForkScanner#setParallelStartPredicate is actually specific to ForkScanner, so this is a breaking change for anyone using that method unless you update it to use Guava's Predicate (but I don't see any callers and that method was already deprecated, so maybe it should just be deleted?).

@rsandell rsandell requested review from jtnord and rsandell June 29, 2021 08:40
@jglick jglick mentioned this pull request Nov 1, 2021
@olamy olamy marked this pull request as draft November 18, 2021 00:59
@timja
Copy link
Member

timja commented Jan 10, 2022

@olamy do you plan to revisit this? (hit in jenkinsci/junit-realtime-test-reporter-plugin#33 (comment))

@jglick
Copy link
Member

jglick commented Jul 1, 2022

Conflicts with #177.

@olamy
Copy link
Member Author

olamy commented Jul 5, 2022

old work. better to forget this.

@olamy olamy closed this Jul 5, 2022
@olamy olamy deleted the get-rid-of-guava branch July 5, 2022 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants