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

mmiller pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new db22fdd  Improve fetching scans and compactions in Monitor (#2294)
db22fdd is described below

commit db22fdd03db44a44ae87c6ae8add23edc63c21e8
Author: Mike Miller <mmil...@apache.org>
AuthorDate: Fri Oct 1 11:17:21 2021 -0400

    Improve fetching scans and compactions in Monitor (#2294)
    
    * Drop fetchScans and fetchCompactions threads and just let the page
    refresh get the data as needed. Created constant to prevent fetching
    more than once a minute. Created time constant for age off
    * Replace active scans table with datatables and add fetched column
    * Add fetched column to Active compactions table
    * Refactored fetch methods to catch thrift error and log.
    * Made entry point methods getCompactions and getScans synchronized to
    allow removal of synchronized code blocks.
---
 .../java/org/apache/accumulo/monitor/Monitor.java  | 78 ++++++++++------------
 .../monitor/rest/compactions/CompactionInfo.java   | 16 ++---
 .../rest/compactions/CompactionsResource.java      |  2 +-
 .../monitor/rest/scans/ScanInformation.java        | 16 ++---
 .../accumulo/monitor/rest/scans/ScansResource.java |  4 +-
 .../accumulo/monitor/resources/js/compactions.js   | 11 ++-
 .../apache/accumulo/monitor/resources/js/scans.js  | 77 ++++++++++-----------
 .../accumulo/monitor/templates/compactions.ftl     |  1 +
 .../apache/accumulo/monitor/templates/scans.ftl    | 13 ++--
 9 files changed, 108 insertions(+), 110 deletions(-)

diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/Monitor.java 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/Monitor.java
index 6217347..9e48e9d 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/Monitor.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/Monitor.java
@@ -474,28 +474,6 @@ public class Monitor extends AbstractServer implements 
HighlyAvailableService {
       }
     }).start();
 
-    Threads.createThread("Scan scanner", () -> {
-      while (true) {
-        try {
-          fetchScans();
-        } catch (Exception e) {
-          log.warn("{}", e.getMessage(), e);
-        }
-        sleepUninterruptibly(5, TimeUnit.SECONDS);
-      }
-    }).start();
-
-    Threads.createThread("Compaction fetcher", () -> {
-      while (true) {
-        try {
-          fetchCompactions();
-        } catch (Exception e) {
-          log.warn("{}", e.getMessage(), e);
-        }
-        sleepUninterruptibly(5, TimeUnit.SECONDS);
-      }
-    }).start();
-
     monitorInitialized.set(true);
   }
 
@@ -561,6 +539,7 @@ public class Monitor extends AbstractServer implements 
HighlyAvailableService {
         oldest = Math.max(oldest, scan.age);
       }
       this.oldestScan = oldest < 0 ? null : oldest;
+      // use clock time for date friendly display
       this.fetched = System.currentTimeMillis();
     }
   }
@@ -577,6 +556,7 @@ public class Monitor extends AbstractServer implements 
HighlyAvailableService {
         oldest = Math.max(oldest, a.age);
       }
       this.oldest = oldest < 0 ? null : oldest;
+      // use clock time for date friendly display
       this.fetched = System.currentTimeMillis();
     }
   }
@@ -584,56 +564,71 @@ public class Monitor extends AbstractServer implements 
HighlyAvailableService {
   private final Map<HostAndPort,ScanStats> allScans = new HashMap<>();
   private final Map<HostAndPort,CompactionStats> allCompactions = new 
HashMap<>();
   private final RecentLogs recentLogs = new RecentLogs();
+  private long scansFetchedNanos = 0L;
+  private long compactsFetchedNanos = 0L;
+  private final long fetchTimeNanos = TimeUnit.MINUTES.toNanos(1);
+  private final long ageOffEntriesMillis = TimeUnit.MINUTES.toMillis(15);
 
-  public Map<HostAndPort,ScanStats> getScans() {
-    synchronized (allScans) {
-      return new HashMap<>(allScans);
+  /**
+   * Fetch the active scans but only if fetchTimeNanos has elapsed.
+   */
+  public synchronized Map<HostAndPort,ScanStats> getScans() {
+    if (System.nanoTime() - scansFetchedNanos > fetchTimeNanos) {
+      log.info("User initiated fetch of Active Scans");
+      fetchScans();
     }
+    return Map.copyOf(allScans);
   }
 
-  public Map<HostAndPort,CompactionStats> getCompactions() {
-    synchronized (allCompactions) {
-      return new HashMap<>(allCompactions);
+  /**
+   * Fetch the active compactions but only if fetchTimeNanos has elapsed.
+   */
+  public synchronized Map<HostAndPort,CompactionStats> getCompactions() {
+    if (System.nanoTime() - compactsFetchedNanos > fetchTimeNanos) {
+      log.info("User initiated fetch of Active Compactions");
+      fetchCompactions();
     }
+    return Map.copyOf(allCompactions);
   }
 
-  private void fetchScans() throws Exception {
+  private void fetchScans() {
     ServerContext context = getContext();
     for (String server : context.instanceOperations().getTabletServers()) {
       final HostAndPort parsedServer = HostAndPort.fromString(server);
-      Client tserver = ThriftUtil.getTServerClient(parsedServer, context);
+      Client tserver = null;
       try {
+        tserver = ThriftUtil.getTServerClient(parsedServer, context);
         List<ActiveScan> scans = tserver.getActiveScans(null, 
context.rpcCreds());
-        synchronized (allScans) {
-          allScans.put(parsedServer, new ScanStats(scans));
-        }
+        allScans.put(parsedServer, new ScanStats(scans));
+        scansFetchedNanos = System.nanoTime();
       } catch (Exception ex) {
-        log.debug("Failed to get active scans from {}", server, ex);
+        log.error("Failed to get active scans from {}", server, ex);
       } finally {
         ThriftUtil.returnClient(tserver);
       }
     }
     // Age off old scan information
     Iterator<Entry<HostAndPort,ScanStats>> entryIter = 
allScans.entrySet().iterator();
+    // clock time used for fetched for date friendly display
     long now = System.currentTimeMillis();
     while (entryIter.hasNext()) {
       Entry<HostAndPort,ScanStats> entry = entryIter.next();
-      if (now - entry.getValue().fetched > 5 * 60 * 1000) {
+      if (now - entry.getValue().fetched > ageOffEntriesMillis) {
         entryIter.remove();
       }
     }
   }
 
-  private void fetchCompactions() throws Exception {
+  private void fetchCompactions() {
     ServerContext context = getContext();
     for (String server : context.instanceOperations().getTabletServers()) {
       final HostAndPort parsedServer = HostAndPort.fromString(server);
-      Client tserver = ThriftUtil.getTServerClient(parsedServer, context);
+      Client tserver = null;
       try {
+        tserver = ThriftUtil.getTServerClient(parsedServer, context);
         var compacts = tserver.getActiveCompactions(null, context.rpcCreds());
-        synchronized (allCompactions) {
-          allCompactions.put(parsedServer, new CompactionStats(compacts));
-        }
+        allCompactions.put(parsedServer, new CompactionStats(compacts));
+        compactsFetchedNanos = System.nanoTime();
       } catch (Exception ex) {
         log.debug("Failed to get active compactions from {}", server, ex);
       } finally {
@@ -642,10 +637,11 @@ public class Monitor extends AbstractServer implements 
HighlyAvailableService {
     }
     // Age off old compaction information
     var entryIter = allCompactions.entrySet().iterator();
+    // clock time used for fetched for date friendly display
     long now = System.currentTimeMillis();
     while (entryIter.hasNext()) {
       var entry = entryIter.next();
-      if (now - entry.getValue().fetched > 5 * 60 * 1000) {
+      if (now - entry.getValue().fetched > ageOffEntriesMillis) {
         entryIter.remove();
       }
     }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionInfo.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionInfo.java
index 5bb6bff..318a8b1 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionInfo.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionInfo.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.monitor.rest.compactions;
 
 import org.apache.accumulo.core.master.thrift.TabletServerStatus;
+import org.apache.accumulo.monitor.Monitor;
 
 /**
  * Generates a compaction info JSON object
@@ -30,6 +31,7 @@ public class CompactionInfo {
   // Variable names become JSON keys
   public String server;
 
+  public long fetched;
   public long count;
   public Long oldest;
 
@@ -37,17 +39,11 @@ public class CompactionInfo {
 
   /**
    * Stores new compaction information
-   *
-   * @param tserverInfo
-   *          status of the tserver
-   * @param count
-   *          number of compactions
-   * @param oldest
-   *          time of oldest compaction
    */
-  public CompactionInfo(TabletServerStatus tserverInfo, long count, Long 
oldest) {
+  public CompactionInfo(TabletServerStatus tserverInfo, 
Monitor.CompactionStats stats) {
     this.server = tserverInfo.getName();
-    this.count = count;
-    this.oldest = oldest;
+    this.fetched = stats.fetched;
+    this.count = stats.count;
+    this.oldest = stats.oldest;
   }
 }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionsResource.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionsResource.java
index 9af29b0..16ea808 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionsResource.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/compactions/CompactionsResource.java
@@ -61,7 +61,7 @@ public class CompactionsResource {
     for (TabletServerStatus tserverInfo : mmi.getTServerInfo()) {
       var stats = entry.get(HostAndPort.fromString(tserverInfo.name));
       if (stats != null) {
-        compactions.addCompaction(new CompactionInfo(tserverInfo, stats.count, 
stats.oldest));
+        compactions.addCompaction(new CompactionInfo(tserverInfo, stats));
       }
     }
     return compactions;
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScanInformation.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScanInformation.java
index 1070e19..3cd202d 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScanInformation.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScanInformation.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.monitor.rest.scans;
 
 import org.apache.accumulo.core.master.thrift.TabletServerStatus;
+import org.apache.accumulo.monitor.Monitor;
 
 /**
  * Generates a scan JSON object
@@ -30,6 +31,7 @@ public class ScanInformation {
   // Variable names become JSON keys
   public String server;
 
+  public long fetched;
   public long scanCount;
   public Long oldestScan;
 
@@ -37,17 +39,11 @@ public class ScanInformation {
 
   /**
    * Stores new scan information
-   *
-   * @param tserverInfo
-   *          status of the tserver
-   * @param scanCount
-   *          number of scans
-   * @param oldestScan
-   *          time of oldest scan
    */
-  public ScanInformation(TabletServerStatus tserverInfo, long scanCount, Long 
oldestScan) {
+  public ScanInformation(TabletServerStatus tserverInfo, Monitor.ScanStats 
stats) {
     this.server = tserverInfo.getName();
-    this.scanCount = scanCount;
-    this.oldestScan = oldestScan;
+    this.fetched = stats.fetched;
+    this.scanCount = stats.scanCount;
+    this.oldestScan = stats.oldestScan;
   }
 }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScansResource.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScansResource.java
index c43c44b..a7ed936 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScansResource.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/scans/ScansResource.java
@@ -50,7 +50,7 @@ public class ScansResource {
    * @return Scan JSON object
    */
   @GET
-  public Scans getActiveScans() {
+  public Scans getActiveScans() throws Exception {
     Scans scans = new Scans();
     ManagerMonitorInfo mmi = monitor.getMmi();
     if (mmi == null) {
@@ -63,7 +63,7 @@ public class ScansResource {
     for (TabletServerStatus tserverInfo : mmi.getTServerInfo()) {
       ScanStats stats = entry.get(HostAndPort.fromString(tserverInfo.name));
       if (stats != null) {
-        scans.addScan(new ScanInformation(tserverInfo, stats.scanCount, 
stats.oldestScan));
+        scans.addScan(new ScanInformation(tserverInfo, stats));
       }
     }
     return scans;
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactions.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactions.js
index 570dbb6..f872e73 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactions.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactions.js
@@ -36,7 +36,13 @@
                if(type === 'display') data = timeDuration(data);
                return data;
              }
-           }
+           },
+           { "targets": "date",
+               "render": function ( data, type, row ) {
+                 if(type === 'display') data = dateFormat(data);
+                 return data;
+               }
+             }
          ],
        "columns": [
          { "data": "server",
@@ -49,7 +55,8 @@
            }
          },
          { "data": "count" },
-         { "data": "oldest" }
+         { "data": "oldest" },
+         { "data": "fetched" },
        ]
      });
  });
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/scans.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/scans.js
index d323be7..a8843fb 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/scans.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/scans.js
@@ -21,55 +21,56 @@
  * Creates scans initial table
  */
 $(document).ready(function() {
-  refreshScans();
+// Create a table for scans list
+     scansList = $('#scansList').DataTable({
+       "ajax": {
+         "url": '/rest/scans',
+         "dataSrc": "scans"
+       },
+       "stateSave": true,
+       "dom": 't<"align-left"l>p',
+       "columnDefs": [
+           { "targets": "duration",
+             "render": function ( data, type, row ) {
+               if(type === 'display') data = timeDuration(data);
+               return data;
+             }
+           },
+           { "targets": "date",
+               "render": function ( data, type, row ) {
+                 if(type === 'display') data = dateFormat(data);
+                 return data;
+               }
+             }
+         ],
+       "columns": [
+         { "data": "server",
+           "type": "html",
+           "render": function ( data, type, row, meta ) {
+             if(type === 'display') {
+                data = '<a href="/tservers?s=' + row.server + '">' + 
row.server + '</a>';
+             }
+             return data;
+           }
+         },
+         { "data": "scanCount" },
+         { "data": "oldestScan" },
+         { "data": "fetched" },
+       ]
+     });
 });
 
-/**
- * Makes the REST calls, generates the tables with the new information
- */
-function refreshScans() {
-  getScans().then(function() {
-    refreshScansTable();
-  });
-}
 
 /**
  * Used to redraw the page
  */
 function refresh() {
-  refreshScans();
+  refreshScansTable();
 }
 
 /**
  * Generates the scans table
  */
 function refreshScansTable() {
-  clearTableBody('scanStatus');
-
-  var data = sessionStorage.scans === undefined ?
-      [] : JSON.parse(sessionStorage.scans);
-
-  if (data.length === 0 || data.scans.length === 0) {
-    var items = createEmptyRow(3, 'Empty');
-
-    $('<tr/>', {
-      html: items
-    }).appendTo('#scanStatus tbody');
-  } else {
-    $.each(data.scans, function(key, val) {
-      var items = [];
-
-      items.push(createFirstCell(val.server,
-          '<a href="/tservers?s=' + val.server + '">' + val.server +
-          '</a>'));
-
-      items.push(createRightCell(val.scanCount, val.scanCount));
-
-      items.push(createRightCell(val.oldestScan, 
timeDuration(val.oldestScan)));
-
-      $('<tr/>', {
-        html: items.join('')
-      }).appendTo('#scanStatus tbody');
-    });
-  }
+   if(scansList) scansList.ajax.reload(null, false ); // user paging is not 
reset on reload
 }
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/compactions.ftl
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/compactions.ftl
index 22ea801..6209536 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/compactions.ftl
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/compactions.ftl
@@ -31,6 +31,7 @@
                 <th class="firstcell">Server&nbsp;</th>
                 <th title="Number of compactions presently 
running">#&nbsp;</th>
                 <th class="duration" title="The age of the oldest compaction 
on this server.">Oldest&nbsp;Age&nbsp;</th>
+                <th class="date" title="Last time data was fetched. Server 
fetches on page refresh, at most every minute.">Fetched</th>
               </tr>
             </thead>
             <tbody></tbody>
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/scans.ftl
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/scans.ftl
index a4670a7..cf83ff7 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/scans.ftl
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/scans.ftl
@@ -25,13 +25,14 @@
       </div>
       <div class="row">
         <div class="col-xs-12">
-          <table id="scanStatus" class="table table-bordered table-striped 
table-condensed">
+          <table id="scansList" class="table table-bordered table-striped 
table-condensed">
             <thead>
-              <tr>
-                <th class="firstcell">Server&nbsp;</th>
-                <th title="Number of scans presently running">#&nbsp;</th>
-                <th title="The age of the oldest scan on this 
server.">Oldest&nbsp;Age&nbsp;</th>
-              </tr>
+             <tr>
+               <th class="firstcell">Server&nbsp;</th>
+               <th title="Number of scans presently running">#&nbsp;</th>
+               <th class="duration" title="The age of the oldest scan on this 
server.">Oldest&nbsp;Age&nbsp;</th>
+               <th class="date" title="Last time data was fetched. Server 
fetches on page refresh, at most every minute.">Fetched</th>
+             </tr>
             </thead>
             <tbody></tbody>
           </table>

Reply via email to