github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/reports/containers/problemRanges/connectionsTable.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import _ from "lodash";
    12  import classNames from "classnames";
    13  import React from "react";
    14  import { Link } from "react-router-dom";
    15  
    16  import * as protos from "src/js/protos";
    17  import { CachedDataReducerState } from "src/redux/cachedDataReducer";
    18  
    19  interface ConnectionTableColumn {
    20    title: string;
    21    extract: (
    22      p: protos.cockroach.server.serverpb.ProblemRangesResponse.INodeProblems,
    23      id?: number,
    24    ) => React.ReactNode;
    25  }
    26  
    27  interface ConnectionsTableProps {
    28    problemRanges: CachedDataReducerState<protos.cockroach.server.serverpb.ProblemRangesResponse>;
    29  }
    30  
    31  const connectionTableColumns: ConnectionTableColumn[] = [
    32    {
    33      title: "Node",
    34      extract: (_problem, id) => (
    35        <Link className="debug-link" to={`/reports/problemranges/${id}`}>
    36          n{id}
    37        </Link>
    38      ),
    39    },
    40    { title: "Unavailable", extract: (problem) => problem.unavailable_range_ids.length },
    41    { title: "No Raft Leader", extract: (problem) => problem.no_raft_leader_range_ids.length },
    42    { title: "Invalid Lease", extract: (problem) => problem.no_lease_range_ids.length },
    43    {
    44      title: "Raft Leader but not Lease Holder",
    45      extract: (problem) => problem.raft_leader_not_lease_holder_range_ids.length,
    46    },
    47    {
    48      title: "Underreplicated (or slow)",
    49      extract: (problem) => problem.underreplicated_range_ids.length,
    50    },
    51    {
    52      title: "Overreplicated",
    53      extract: (problem) => problem.overreplicated_range_ids.length,
    54    },
    55    {
    56      title: "Quiescent equals ticking",
    57      extract: (problem) => problem.quiescent_equals_ticking_range_ids.length,
    58    },
    59    {
    60      title: "Raft log too large",
    61      extract: (problem) => problem.raft_log_too_large_range_ids.length,
    62    },
    63    {
    64      title: "Total",
    65      extract: (problem) => {
    66        return problem.unavailable_range_ids.length +
    67          problem.no_raft_leader_range_ids.length +
    68          problem.no_lease_range_ids.length +
    69          problem.raft_leader_not_lease_holder_range_ids.length +
    70          problem.underreplicated_range_ids.length +
    71          problem.overreplicated_range_ids.length +
    72          problem.quiescent_equals_ticking_range_ids.length +
    73          problem.raft_log_too_large_range_ids.length;
    74      },
    75    },
    76    { title: "Error", extract: (problem) => problem.error_message },
    77  ];
    78  
    79  export default function ConnectionsTable(props: ConnectionsTableProps) {
    80    const { problemRanges } = props;
    81    // lastError is already handled by ProblemRanges component.
    82    if (_.isNil(problemRanges) ||
    83      _.isNil(problemRanges.data) ||
    84      !_.isNil(problemRanges.lastError)) {
    85      return null;
    86    }
    87    const { data } = problemRanges;
    88    const ids = _.chain(_.keys(data.problems_by_node_id))
    89      .map(id => parseInt(id, 10))
    90      .sortBy(id => id)
    91      .value();
    92    return (
    93      <div>
    94        <h2 className="base-heading">Connections (via Node {data.node_id})</h2>
    95        <table className="connections-table">
    96          <tbody>
    97            <tr className="connections-table__row connections-table__row--header">
    98              {
    99                _.map(connectionTableColumns, (col, key) => (
   100                  <th key={key} className="connections-table__cell connections-table__cell--header">
   101                    {col.title}
   102                  </th>
   103                ))
   104              }
   105            </tr>
   106            {
   107              _.map(ids, id => {
   108                const rowProblems = data.problems_by_node_id[id];
   109                const rowClassName = classNames({
   110                  "connections-table__row": true,
   111                  "connections-table__row--warning": !_.isEmpty(rowProblems.error_message),
   112                });
   113                return (
   114                  <tr key={id} className={rowClassName}>
   115                    {
   116                      _.map(connectionTableColumns, (col, key) => (
   117                        <td key={key} className="connections-table__cell">
   118                          {col.extract(rowProblems, id)}
   119                        </td>
   120                      ))
   121                    }
   122                  </tr>
   123                );
   124              })
   125            }
   126          </tbody>
   127        </table>
   128      </div>
   129    );
   130  }