stefan-egli commented on code in PR #20:
URL:
https://github.com/apache/sling-org-apache-sling-discovery-oak/pull/20#discussion_r3730608551
##########
src/main/java/org/apache/sling/discovery/oak/OakDiscoveryService.java:
##########
@@ -581,6 +604,80 @@ public void updateProperties() {
}
}
+ /**
+ * Returns {@code true} when this component or the framework is shutting
+ * down. Latches {@link #deactivating} on first observation so subsequent
+ * calls are a single volatile read. Package-private for unit testing.
+ */
+ boolean isShuttingDown() {
+ if (deactivating) {
+ return true;
+ }
+ final Bundle sb = systemBundle.get();
+ if (sb == null) {
+ return false;
+ }
+ try {
+ final int state = sb.getState();
+ if (state == Bundle.STOPPING
+ || state == Bundle.RESOLVED
+ || state == Bundle.INSTALLED
+ || state == Bundle.UNINSTALLED) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle state {} observed -
"
+ + "OakDiscoveryService will skip further property
writes", state);
+ return true;
+ }
+ } catch (IllegalStateException e) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle reference invalidated -
"
+ + "OakDiscoveryService will skip further property writes");
Review Comment:
`logger.info` sounds fine, but perhaps logging the exception wouldn't hurt?
```suggestion
logger.info("isShuttingDown: system bundle reference invalidated
- "
+ "OakDiscoveryService will skip further property writes
: {}", e.toString());
```
##########
src/main/java/org/apache/sling/discovery/oak/OakDiscoveryService.java:
##########
@@ -581,6 +604,80 @@ public void updateProperties() {
}
}
+ /**
+ * Returns {@code true} when this component or the framework is shutting
+ * down. Latches {@link #deactivating} on first observation so subsequent
+ * calls are a single volatile read. Package-private for unit testing.
+ */
+ boolean isShuttingDown() {
+ if (deactivating) {
+ return true;
+ }
+ final Bundle sb = systemBundle.get();
+ if (sb == null) {
+ return false;
+ }
+ try {
+ final int state = sb.getState();
+ if (state == Bundle.STOPPING
+ || state == Bundle.RESOLVED
+ || state == Bundle.INSTALLED
+ || state == Bundle.UNINSTALLED) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle state {} observed -
"
+ + "OakDiscoveryService will skip further property
writes", state);
+ return true;
+ }
+ } catch (IllegalStateException e) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle reference invalidated -
"
+ + "OakDiscoveryService will skip further property writes");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test-only hook to install a system-bundle reference without going
+ * through {@link #cacheSystemBundle()}.
+ */
+ void setSystemBundleForTesting(final Bundle bundle) {
+ this.systemBundle.set(bundle);
+ }
+
+ private void cacheSystemBundle() {
+ cacheSystemBundle(FrameworkUtil.getBundle(OakDiscoveryService.class));
+ }
+
+ /**
+ * Package-private overload taking the caller-bundle explicitly, so unit
+ * tests can exercise the {@link BundleContext} failure branches without
+ * an OSGi framework.
+ */
+ void cacheSystemBundle(final Bundle ourBundle) {
+ if (ourBundle == null) {
+ logger.debug("cacheSystemBundle: no OSGi framework detected via
FrameworkUtil"
+ + " - shutdown detection degrades to deactivate() only");
Review Comment:
might be worth a `logger.info`?
##########
src/main/java/org/apache/sling/discovery/oak/OakDiscoveryService.java:
##########
@@ -581,6 +604,80 @@ public void updateProperties() {
}
}
+ /**
+ * Returns {@code true} when this component or the framework is shutting
+ * down. Latches {@link #deactivating} on first observation so subsequent
+ * calls are a single volatile read. Package-private for unit testing.
+ */
+ boolean isShuttingDown() {
+ if (deactivating) {
+ return true;
+ }
+ final Bundle sb = systemBundle.get();
+ if (sb == null) {
+ return false;
+ }
+ try {
+ final int state = sb.getState();
+ if (state == Bundle.STOPPING
+ || state == Bundle.RESOLVED
+ || state == Bundle.INSTALLED
+ || state == Bundle.UNINSTALLED) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle state {} observed -
"
+ + "OakDiscoveryService will skip further property
writes", state);
+ return true;
+ }
+ } catch (IllegalStateException e) {
+ deactivating = true;
+ logger.info("isShuttingDown: system bundle reference invalidated -
"
+ + "OakDiscoveryService will skip further property writes");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test-only hook to install a system-bundle reference without going
+ * through {@link #cacheSystemBundle()}.
+ */
+ void setSystemBundleForTesting(final Bundle bundle) {
+ this.systemBundle.set(bundle);
+ }
+
+ private void cacheSystemBundle() {
+ cacheSystemBundle(FrameworkUtil.getBundle(OakDiscoveryService.class));
+ }
+
+ /**
+ * Package-private overload taking the caller-bundle explicitly, so unit
+ * tests can exercise the {@link BundleContext} failure branches without
+ * an OSGi framework.
+ */
+ void cacheSystemBundle(final Bundle ourBundle) {
+ if (ourBundle == null) {
+ logger.debug("cacheSystemBundle: no OSGi framework detected via
FrameworkUtil"
+ + " - shutdown detection degrades to deactivate() only");
+ return;
+ }
+ try {
+ final BundleContext ctx = ourBundle.getBundleContext();
+ if (ctx == null) {
+ logger.debug("cacheSystemBundle: our BundleContext is null"
+ + " - shutdown detection degrades to deactivate()
only");
Review Comment:
same here, maybe worth a `logger.info` instead?
##########
src/main/java/org/apache/sling/discovery/oak/OakDiscoveryService.java:
##########
@@ -319,6 +335,9 @@ protected void activate(final BundleContext bundleContext) {
*/
@Deactivate
protected void deactivate() {
+ // set before acquiring any lock so concurrent PropertyProvider
+ // callbacks short-circuit in doUpdateProperties()
+ deactivating = true;
Review Comment:
as there is no trace of the new behaviour (depending on `isShuttingDown()`
of course, but `doUpdateProperties()` does only `logger.debug`) - what about
adding a `logger.info` here saying something like "further updates will be
suppressed" or similar? it could also be a good marker that makes it clear that
this new version would be in use.
##########
src/main/java/org/apache/sling/discovery/oak/OakDiscoveryService.java:
##########
@@ -105,6 +108,17 @@ public class OakDiscoveryService extends
BaseDiscoveryService {
**/
private volatile boolean activated = false;
+ /**
+ * Latched to {@code true} once this component or the OSGi framework begins
+ * shutting down. See {@link #isShuttingDown()}.
+ */
+ private volatile boolean deactivating = false;
+
+ /**
+ * Cached system bundle (bundle 0), resolved once at activation.
+ */
+ private final AtomicReference<Bundle> systemBundle = new
AtomicReference<>();
Review Comment:
nit: any advantage of using `AtomicReference` here vs the previous `private
volatile Bundle systemBundle` ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]