-
Notifications
You must be signed in to change notification settings - Fork 38
AP-24824: Addeds a refresh path in getCategories() so dev-mode extens… #70
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -90,6 +90,7 @@ | |||||
| import org.knime.core.webui.node.view.NodeView; | ||||||
| import org.knime.core.webui.node.view.NodeViewFactory; | ||||||
| import org.knime.python3.nodes.DelegatingNodeModel; | ||||||
| import org.knime.python3.nodes.PythonExtensionPreferences; | ||||||
| import org.knime.python3.nodes.dialog.DelegatingJsonSettingsDataService; | ||||||
| import org.knime.python3.nodes.dialog.JsonFormsNodeDialog; | ||||||
| import org.knime.python3.nodes.ports.PythonPortTypeRegistry; | ||||||
|
|
@@ -108,6 +109,8 @@ public abstract class ExtensionNodeSetFactory implements NodeSetFactory, Categor | |||||
|
|
||||||
| private static final Map<String, KnimeExtension> ALL_EXTENSIONS = new ConcurrentHashMap<>(); | ||||||
|
|
||||||
| private final Supplier<Stream<? extends KnimeExtension>> m_extensionSupplier; | ||||||
|
|
||||||
| private final Map<String, KnimeExtension> m_extensions; | ||||||
|
|
||||||
| private final Map<NodeId, ExtensionNode> m_allNodes; | ||||||
|
|
@@ -120,17 +123,31 @@ public abstract class ExtensionNodeSetFactory implements NodeSetFactory, Categor | |||||
| * @param extensionSupplier supplier for a {@link Stream} of {@link KnimeExtension} objects. | ||||||
| */ | ||||||
| protected ExtensionNodeSetFactory(final Supplier<Stream<? extends KnimeExtension>> extensionSupplier) { | ||||||
| m_extensions = extensionSupplier.get().collect(toMap(KnimeExtension::getId, Function.identity())); | ||||||
| ALL_EXTENSIONS.putAll(m_extensions); | ||||||
| m_extensionSupplier = extensionSupplier; | ||||||
| m_extensions = new HashMap<>(); | ||||||
| m_allNodes = new HashMap<>(); | ||||||
| m_allCategories = new ArrayList<>(); | ||||||
| for (var extension : m_extensions.values()) { | ||||||
| refreshCaches(); | ||||||
| } | ||||||
|
|
||||||
| private synchronized void refreshCaches() { | ||||||
| var extensions = m_extensionSupplier.get().collect(toMap(KnimeExtension::getId, Function.identity())); | ||||||
| m_extensions.clear(); | ||||||
| m_extensions.putAll(extensions); | ||||||
| ALL_EXTENSIONS.putAll(extensions); | ||||||
| m_allNodes.clear(); | ||||||
| m_allCategories.clear(); | ||||||
| for (var extension : extensions.values()) { | ||||||
| var extensionId = extension.getId(); | ||||||
| extension.getNodes().forEach(n -> m_allNodes.put(new NodeId(extensionId, n.getId()), n)); | ||||||
| extension.getCategories().forEach(c -> m_allCategories.add(c)); | ||||||
| } | ||||||
| } | ||||||
|
Comment on lines
+133
to
145
|
||||||
|
|
||||||
| private static boolean hasCustomExtensions() { | ||||||
| return PythonExtensionPreferences.getPathsToCustomExtensions().findAny().isPresent(); | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public final Collection<String> getNodeFactoryIds() { | ||||||
| return m_allNodes.entrySet().stream().filter(entry -> !entry.getValue().isHidden()) | ||||||
|
|
@@ -164,6 +181,9 @@ public final ConfigRO getAdditionalSettings(final String id) { | |||||
|
|
||||||
| @Override | ||||||
| public Collection<CategoryExtension> getCategories() { | ||||||
| if (hasCustomExtensions()) { | ||||||
| refreshCaches(); | ||||||
| } | ||||||
|
Comment on lines
183
to
+186
|
||||||
| return m_allCategories; | ||||||
|
||||||
| return m_allCategories; | |
| return List.copyOf(m_allCategories); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refreshCaches() updates ALL_EXTENSIONS via putAll() but never removes entries that are no longer provided by the supplier. If custom extension paths change during dev-mode, ALL_EXTENSIONS can retain stale KnimeExtension instances indefinitely (memory leak) and DynamicExtensionNodeFactory may still resolve removed extensions. Consider clearing ALL_EXTENSIONS first (or retaining only current keys) before repopulating.