[NO ISSUE][STO] Notify of completion of IO request in finally

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Notify completion of a request in a finally clause to ensure
  waiting thread is always notified.

Change-Id: I8b3003b47b6b181856faf82aca6e828ee014527c
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2839
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IoRequest.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IoRequest.java
index 8c81d41..93e38f5 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IoRequest.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/io/IoRequest.java
@@ -44,7 +44,7 @@
     private long offset;
     private ByteBuffer data;
     private ByteBuffer[] dataArray;
-    private HyracksDataException failure;
+    private Throwable failure;
     private int read;
     private int write;
     private long writes;
@@ -133,15 +133,17 @@
             state = State.OPERATION_SUCCEEDED;
         } catch (Throwable th) { // NOSONAR: This method must never throw anything
             state = State.OPERATION_FAILED;
-            failure = HyracksDataException.create(th);
+            failure = th;
+        } finally {
+            notifyAll();
         }
-        notifyAll();
     }
 
     public State getState() {
         return state;
     }
 
+    @SuppressWarnings("squid:S899") // Offer failing means we're over capacity and this should be garbage collected
     void recycle() {
         reset();
         freeRequests.offer(this);
@@ -165,6 +167,6 @@
     }
 
     public HyracksDataException getFailure() {
-        return failure;
+        return HyracksDataException.create(failure);
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
index 3eea0a9..8e2ff01 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
@@ -142,9 +142,7 @@
             }
             entranceSuccessful = numEntered == components.size();
         } catch (Throwable e) { // NOSONAR: Log and re-throw
-            if (LOGGER.isErrorEnabled()) {
-                LOGGER.log(Level.ERROR, opType.name() + " failed to enter components on " + lsmIndex, e);
-            }
+            LOGGER.warn("{} failed to enter components on {}", opType.name(), lsmIndex, e);
             throw e;
         } finally {
             if (!entranceSuccessful) {
@@ -201,9 +199,7 @@
                     ctx.setAccessingComponents(false);
                     exitOperation(ctx, opType, newComponent, failedOperation);
                 } catch (Throwable e) { // NOSONAR: Log and re-throw
-                    if (LOGGER.isErrorEnabled()) {
-                        LOGGER.log(Level.ERROR, e.getMessage(), e);
-                    }
+                    LOGGER.warn("Failure exiting components", e);
                     throw e;
                 } finally {
                     if (failedOperation && (opType == LSMOperationType.MODIFICATION
@@ -710,9 +706,7 @@
                 processor.finish();
             }
         } catch (HyracksDataException e) {
-            if (LOGGER.isErrorEnabled()) {
-                LOGGER.log(Level.ERROR, "Failed to process frame", e);
-            }
+            LOGGER.warn("Failed to process frame", e);
             throw e;
         } finally {
             exit(ctx);