You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/09/26 09:33:47 UTC

[causeway] branch master updated: CAUSEWAY-3603: handle exceptions well with the Lazy type

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new c82fe8b4a1 CAUSEWAY-3603: handle exceptions well with the Lazy type
c82fe8b4a1 is described below

commit c82fe8b4a15ddc2569e7af46764edf1dc4d3ff10
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Sep 26 11:33:42 2023 +0200

    CAUSEWAY-3603: handle exceptions well with the Lazy type
---
 .../org/apache/causeway/commons/internal/base/_Lazy.java  | 15 +++++++++------
 .../causeway/commons/internal/base/_Lazy_Simple.java      | 15 +++++++++------
 .../causeway/commons/internal/base/_Lazy_ThreadSafe.java  | 15 +++++++++------
 .../causeway/commons/internal/binding/_Observables.java   |  6 +++---
 4 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy.java b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy.java
index 8021faca4c..c7e451ea7e 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy.java
@@ -21,6 +21,8 @@ package org.apache.causeway.commons.internal.base;
 import java.util.Optional;
 import java.util.function.Supplier;
 
+import org.apache.causeway.commons.functional.ThrowingSupplier;
+
 /**
  * <h1>- internal use only -</h1>
  * <p>
@@ -53,7 +55,8 @@ public interface _Lazy<T> extends Supplier<T> {
      * Evaluates this lazy value and memoizes it, when called the first time
      * after initialization or clear().
      * <p>
-     * Postcondition when memoization throws an exception: isMemoized()->true and get()->null
+     * Postcondition when memoization throws an exception: isMemoized()->true and get()->null.
+     * In other words: the _Lazy needs to be cleared before it can be re-memoized.
      */
     @Override
     public T get();
@@ -77,21 +80,21 @@ public interface _Lazy<T> extends Supplier<T> {
      * Concurrent calls to this lazy's get() method might result in concurrent calls to the
      * specified {@code supplier}.
      * @param supplier
-     * @return an (non-thread-safe) instance of _Lacy that initializes with the specified {@code supplier}
+     * @return an (non-thread-safe) instance of _Lazy that initializes with the specified {@code supplier}
      */
-    public static <T> _Lazy<T> of(Supplier<? extends T> supplier) {
+    public static <T> _Lazy<T> of(final ThrowingSupplier<? extends T> supplier) {
         return new _Lazy_Simple<T>(supplier);
     }
 
     /**
-     * Thread-safe variant to {@link _Lazy#of(Supplier)}.
+     * Thread-safe variant to {@link _Lazy#of(ThrowingSupplier)}.
      * <p>
      * Concurrent calls to this lazy's get() method will never result in concurrent calls to the
      * specified {@code supplier}.
      * @param supplier
-     * @return an (thread-safe) instance of _Lacy that initializes with the specified {@code supplier}
+     * @return an (thread-safe) instance of _Lazy that initializes with the specified {@code supplier}
      */
-    public static <T> _Lazy<T> threadSafe(Supplier<? extends T> supplier) {
+    public static <T> _Lazy<T> threadSafe(final ThrowingSupplier<? extends T> supplier) {
         return new _Lazy_ThreadSafe<T>(supplier);
     }
 
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_Simple.java b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_Simple.java
index 336b6fcca3..58b57b835f 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_Simple.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_Simple.java
@@ -19,8 +19,8 @@
 package org.apache.causeway.commons.internal.base;
 
 import java.util.Optional;
-import java.util.function.Supplier;
 
+import org.apache.causeway.commons.functional.ThrowingSupplier;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 
 import lombok.NonNull;
@@ -31,12 +31,12 @@ import lombok.NonNull;
  */
 final class _Lazy_Simple<T> implements _Lazy<T> {
 
-    private final Supplier<? extends T> supplier;
+    private final ThrowingSupplier<? extends T> supplier;
     private T value;
     private boolean memoized;
     private boolean getting;
 
-    _Lazy_Simple(final @NonNull Supplier<? extends T> supplier) {
+    _Lazy_Simple(final @NonNull ThrowingSupplier<? extends T> supplier) {
         this.supplier = supplier;
     }
 
@@ -60,9 +60,12 @@ final class _Lazy_Simple<T> implements _Lazy<T> {
         }
         guardAgainstRecursiveCall();
         getting = true; // prevent the supplier from doing a nested call
-        value = supplier.get();
-        getting = false;
-        memoized = true;
+        try {
+            value = supplier.get();
+        } finally {
+            getting = false;
+            memoized = true; // post condition as per contract
+        }
         return value;
     }
 
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_ThreadSafe.java b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_ThreadSafe.java
index 2ccc7be7ea..088514d923 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_ThreadSafe.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Lazy_ThreadSafe.java
@@ -19,8 +19,8 @@
 package org.apache.causeway.commons.internal.base;
 
 import java.util.Optional;
-import java.util.function.Supplier;
 
+import org.apache.causeway.commons.functional.ThrowingSupplier;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 
 import lombok.NonNull;
@@ -32,12 +32,12 @@ import lombok.Synchronized;
  */
 final class _Lazy_ThreadSafe<T> implements _Lazy<T> {
 
-    private final Supplier<? extends T> supplier;
+    private final ThrowingSupplier<? extends T> supplier;
     private T value;
     private boolean memoized;
     private boolean getting;
 
-    _Lazy_ThreadSafe(final @NonNull Supplier<? extends T> supplier) {
+    _Lazy_ThreadSafe(final @NonNull ThrowingSupplier<? extends T> supplier) {
         this.supplier = supplier;
     }
 
@@ -62,9 +62,12 @@ final class _Lazy_ThreadSafe<T> implements _Lazy<T> {
         }
         guardAgainstRecursiveCall();
         getting = true; // prevent the supplier from doing a nested call
-        value = supplier.get();
-        getting = false;
-        memoized = true;
+        try {
+            value = supplier.get();
+        } finally {
+            getting = false;
+            memoized = true; // post condition as per contract
+        }
         return value;
     }
 
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/binding/_Observables.java b/commons/src/main/java/org/apache/causeway/commons/internal/binding/_Observables.java
index 552d07c9cd..016fb157a1 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/binding/_Observables.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/binding/_Observables.java
@@ -19,8 +19,8 @@
 package org.apache.causeway.commons.internal.binding;
 
 import java.util.function.BooleanSupplier;
-import java.util.function.Supplier;
 
+import org.apache.causeway.commons.functional.ThrowingSupplier;
 import org.apache.causeway.commons.internal.base._Lazy;
 
 /**
@@ -39,7 +39,7 @@ public class _Observables {
 
         private final _Lazy<T> lazyValue;
 
-        public LazyObservable(final Supplier<T> factory) {
+        public LazyObservable(final ThrowingSupplier<T> factory) {
             this.lazyValue = _Lazy.threadSafe(factory);
         }
 
@@ -60,7 +60,7 @@ public class _Observables {
 
     }
 
-    public static <T> LazyObservable<T> lazy(final Supplier<T> factory) {
+    public static <T> LazyObservable<T> lazy(final ThrowingSupplier<T> factory) {
         return new LazyObservable<T>(factory);
     }