github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/api/ui/debug/js/backfill.js (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  var upsertbatchTable;
    16  
    17  function initSchedulerViewer() {
    18      // Disable null value warning from data table.
    19      $.fn.dataTable.ext.errMode = 'none';
    20  
    21      $.ajax({
    22              url: "/dbg/jobs/backfill",
    23              success: function (body) {
    24                  var runningJobData = []
    25                  var pastRunsData = []
    26                  for (var key in body) {
    27                      var strs = key.split("|")
    28                      var row = body[key]
    29                      row['table'] = strs[0]
    30                      row['shard'] = strs[1]
    31                      row['type'] = strs[2]
    32                      if ('lastDuration' in row) {
    33                          row['lastDuration'] = row['lastDuration'].toDuration()
    34                      }
    35  
    36                      if ('lockDuration' in row) {
    37                          row['lockDuration'] = row['lockDuration'].toDuration()
    38                      }
    39  
    40                      if (row['status'] == 'running') {
    41                          runningJobData.push(row)
    42                      } else {
    43                          // Also get stats like current backfill buffer size and backfilling size, etc.
    44                          $.ajax({
    45                                  url: "/dbg/{0}/{1}".format(row['table'], row['shard']),
    46                                  success: function (body) {
    47                                      var backfillMgr = body["liveStore"]["backfillManager"];
    48                                      if (backfillMgr) {
    49                                          row["numRecords"] = backfillMgr["numRecords"];
    50                                          row["currentBufferSize"] = backfillMgr["currentBufferSize"];
    51                                          row["backfillingBufferSize"] = backfillMgr["backfillingBufferSize"];
    52                                          row["maxBufferSize"] = backfillMgr["maxBufferSize"];
    53                                          row["numUpsertBatches"] = backfillMgr["numUpsertBatches"];
    54                                      }
    55                                  },
    56                                  error: function (xhr) {
    57                                      alert(xhr.responseText);
    58                                  },
    59                                  async: false
    60                              }
    61                          )
    62                          pastRunsData.push(row);
    63                      }
    64                  }
    65                  initRunningJobTable(runningJobData)
    66                  initPastRunTable(pastRunsData)
    67              },
    68              error: function (xhr) {
    69                  alert(xhr.responseText)
    70              }
    71          }
    72      );
    73  
    74      // Init table selector.
    75      $('#table-selector').select2({
    76          ajax: {
    77              url: "/schema/tables",
    78              dataType: 'json',
    79              quietMillis: 50,
    80              processResults: function (data) {
    81                  return {
    82                      results: $.map(data, function (item, idx) {
    83                          return {
    84                              text: item,
    85                              id: idx + 1,
    86                          }
    87                      })
    88                  };
    89              }
    90          },
    91          width: 'resolve'
    92      }).on('change', function () {
    93          refreshBackfillQueue();
    94      });
    95  
    96      // Init shard selector.
    97      $('#shard-selector').select2({
    98          data: [
    99              {
   100                  "id": 0,
   101                  "text": 0,
   102              }
   103          ]
   104      }).on('change', function (e) {
   105          refreshBackfillQueue();
   106      });
   107  }
   108  
   109  function refreshBackfillQueue() {
   110      var table = $('#table-selector').select2('data')[0].text;
   111      var shard = $('#shard-selector').select2('data')[0].text;
   112      if ($('#upsertbatch-selector').select2()) {
   113          $('#upsertbatch-selector').empty();
   114          $('#upsertbatch-selector').select2("destroy");
   115      }
   116  
   117      $('#upsertbatch-selector').select2({
   118          ajax: {
   119              url: "/dbg/{0}/{1}".format(table, shard),
   120              cache: true,
   121              dataType: 'json',
   122              quietMillis: 50,
   123              processResults: function (data) {
   124                  var results = [];
   125                  var numUpsertBatches = data.liveStore.backfillManager.numUpsertBatches;
   126                  for (var i = 0; i < numUpsertBatches; i++) {
   127                      results.push({
   128                          text: i,
   129                          id: i + 1
   130                      });
   131                  }
   132  
   133                  return {
   134                      results: results
   135                  };
   136              }
   137          },
   138          width: '100px',
   139          minimumResultsForSearch: -1
   140      }).on('change', function (e) {
   141          refreshUpsertBatchTable();
   142      });
   143  }
   144  
   145  function refreshUpsertBatchTable() {
   146      var table = $("#table-selector").select2('data')[0].text;
   147      var shard = $("#shard-selector").select2('data')[0].text;
   148      var upsertBatch = $("#upsertbatch-selector").select2('data')[0].text;
   149  
   150      $.ajax({
   151          url: "/dbg/{0}/{1}/backfill-manager/upsertbatches/{2}".format(table, shard, upsertBatch),
   152          success: function (body) {
   153              var columns = body.columnNames.map(function (name) {
   154                      return {"title": name}
   155                  }
   156              );
   157  
   158              // Need to explicitly destroy old data table.
   159              if (upsertbatchTable) {
   160                  upsertbatchTable.destroy();
   161                  $('#upsertbatch-table').empty();
   162              }
   163  
   164              upsertbatchTable = $('#upsertbatch-table').DataTable({
   165                  "serverSide": true,
   166                  "processing": true,
   167                  "paging": true,
   168                  "searching": false,
   169                  "pageLength": 20,
   170                  "lengthMenu": [[1, 10, 25, 50, 100], [1, 10, 25, 50, 100]],
   171                  "columns": columns,
   172                  "ajax": {
   173                      "type": "GET",
   174                      "url": "/dbg/{0}/{1}/backfill-manager/upsertbatches/{2}".format(table, shard, upsertBatch),
   175                      "dataType": "json",
   176                      "contentType": 'application/json'
   177                  }
   178              });
   179          },
   180          error: function (error) {
   181              alert('error: ' + eval(error));
   182          }
   183      });
   184  }
   185  
   186  function submitBackfillJob(table, shard) {
   187      var url = "/dbg/{0}/{1}/backfill".format(table, shard)
   188      $.ajax({
   189              url: url,
   190              method: "POST",
   191              dataType: 'json',
   192              success: function (body) {
   193                  alert(body);
   194                  reloadCurrentTab();
   195              },
   196              error: function (xhr) {
   197                  alert(xhr.responseText);
   198              }
   199          }
   200      )
   201  }
   202  
   203  function initRunningJobTable(data) {
   204      $('#running-job-table').DataTable({
   205          paging: false,
   206          searching: false,
   207          aoColumns: [
   208              {title: "Table", data: "table"},
   209              {title: "Shard", data: "shard", type: "num"},
   210              {title: "Type", data: "type"},
   211              {title: "Stage", data: "stage"},
   212              {title: "Current", data: "current", type: "num"},
   213              {title: "Total", data: "total", type: "num"},
   214          ],
   215          aaData: data,
   216      });
   217  }
   218  
   219  function initPastRunTable(data) {
   220      $('#past-runs-table').DataTable({
   221          paging: true,
   222          searching: true,
   223          pageLength: 20,
   224          lengthMenu: [[1, 10, 25, 50, 100], [1, 10, 25, 50, 100]],
   225          aoColumns: [
   226              {title: "Table", data: "table"},
   227              {title: "Shard", data: "shard", type: "num"},
   228              {title: "Type", data: "type"},
   229              {title: "Status", data: "status"},
   230              {title: "Number of Records Backfilled", data: "numRecords", type: "num"},
   231              {title: "Number of Affected Days", data: "numAffectedDays", type: "num"},
   232              {
   233                  title: "Action",
   234                  mData: null,
   235                  bSortable: false,
   236                  mRender: function (data, type, row) {
   237                      var table = row['table']
   238                      var shard = row['shard']
   239                      return $("<div />").append($(
   240                          "<button class='ui-button' onclick=\"submitBackfillJob('" + table + "'," + shard + ")\">Backfill</button>")).html();
   241                  },
   242              },
   243              {
   244                  title: "Last Error",
   245                  data: "lastError",
   246                  type: "string",
   247                  render: function (data) {
   248                      return JSON.stringify(data)
   249                  }
   250              },
   251              {
   252                  title: "Last Start Time",
   253                  data: "lastStartTime",
   254                  type: "date",
   255                  render: function (data) {
   256                      return new Date(data).toLocaleString()
   257                  }
   258              },
   259              {title: "Last Duration", data: "lastDuration", type: "string"},
   260              {title: "Last Lock Wait Duration", data: "lockDuration", type: "string"},
   261              {title: "Redo Log File", data: "redologFile", type: "number"},
   262              {title: "Batch Offset", data: "batchOffset", type: "number"},
   263              {title: "Number of Records in Queue", data: "numRecords", type: "number"},
   264              {title: "Current Buffer Size", data: "currentBufferSize", type: "number"},
   265              {title: "Backfilling Buffer Size", data: "backfillingBufferSize", type: "number"},
   266              {title: "Max Buffer Size", data: "maxBufferSize", type: "number"},
   267              {title: "Num Upsert Batches", data: "numUpsertBatches", type: "number"},
   268          ],
   269          aaData: data,
   270      });
   271  }