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 }