vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx (about) 1 /** 2 * Copyright 2021 The Vitess Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import { orderBy, groupBy } from 'lodash-es'; 18 import React, { useMemo } from 'react'; 19 import { Link } from 'react-router-dom'; 20 21 import { useWorkflow } from '../../../hooks/api'; 22 import { formatAlias } from '../../../util/tablets'; 23 import { formatDateTime } from '../../../util/time'; 24 import { getStreams, formatStreamKey, getStreamSource, getStreamTarget } from '../../../util/workflows'; 25 import { DataCell } from '../../dataTable/DataCell'; 26 import { DataTable } from '../../dataTable/DataTable'; 27 import { TabletLink } from '../../links/TabletLink'; 28 import { StreamStatePip } from '../../pips/StreamStatePip'; 29 import { WorkflowStreamsLagChart } from '../../charts/WorkflowStreamsLagChart'; 30 import { ShardLink } from '../../links/ShardLink'; 31 import { env } from '../../../util/env'; 32 33 interface Props { 34 clusterID: string; 35 keyspace: string; 36 name: string; 37 } 38 39 const COLUMNS = ['Stream', 'Source', 'Target', 'Tablet']; 40 41 export const WorkflowStreams = ({ clusterID, keyspace, name }: Props) => { 42 const { data } = useWorkflow({ clusterID, keyspace, name }); 43 44 const streams = useMemo(() => { 45 const rows = getStreams(data).map((stream) => ({ 46 key: formatStreamKey(stream), 47 ...stream, 48 })); 49 50 return orderBy(rows, 'streamKey'); 51 }, [data]); 52 53 const streamsByState = groupBy(streams, 'state'); 54 55 const renderRows = (rows: typeof streams) => { 56 return rows.map((row) => { 57 const href = 58 row.tablet && row.id 59 ? `/workflow/${clusterID}/${keyspace}/${name}/stream/${row.tablet.cell}/${row.tablet.uid}/${row.id}` 60 : null; 61 62 const source = getStreamSource(row); 63 const target = getStreamTarget(row, keyspace); 64 65 return ( 66 <tr key={row.key}> 67 <DataCell> 68 <StreamStatePip state={row.state} />{' '} 69 <Link className="font-bold" to={href}> 70 {row.key} 71 </Link> 72 <div className="text-sm text-secondary"> 73 Updated {formatDateTime(row.time_updated?.seconds)} 74 </div> 75 </DataCell> 76 <DataCell> 77 {source ? ( 78 <ShardLink 79 clusterID={clusterID} 80 keyspace={row.binlog_source?.keyspace} 81 shard={row.binlog_source?.shard} 82 > 83 {source} 84 </ShardLink> 85 ) : ( 86 <span className="text-secondary">N/A</span> 87 )} 88 </DataCell> 89 <DataCell> 90 {target ? ( 91 <ShardLink clusterID={clusterID} keyspace={keyspace} shard={row.shard}> 92 {target} 93 </ShardLink> 94 ) : ( 95 <span className="text-secondary">N/A</span> 96 )} 97 </DataCell> 98 <DataCell> 99 <TabletLink alias={formatAlias(row.tablet)} clusterID={clusterID}> 100 {formatAlias(row.tablet)} 101 </TabletLink> 102 </DataCell> 103 </tr> 104 ); 105 }); 106 }; 107 108 return ( 109 <div className="mt-12 mb-16"> 110 {env().REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS && ( 111 <> 112 <h3 className="my-8">Stream VReplication Lag</h3> 113 <WorkflowStreamsLagChart clusterID={clusterID} keyspace={keyspace} workflowName={name} /> 114 </> 115 )} 116 117 <h3 className="mt-24 mb-8">Streams</h3> 118 {/* TODO(doeg): add a protobuf enum for this (https://github.com/vitessio/vitess/projects/12#card-60190340) */} 119 {['Error', 'Copying', 'Running', 'Stopped'].map((streamState) => { 120 if (!Array.isArray(streamsByState[streamState])) { 121 return null; 122 } 123 124 return ( 125 <div className="my-12" key={streamState}> 126 <DataTable 127 columns={COLUMNS} 128 data={streamsByState[streamState]} 129 // TODO(doeg): make pagination optional in DataTable https://github.com/vitessio/vitess/projects/12#card-60810231 130 pageSize={1000} 131 renderRows={renderRows} 132 title={streamState} 133 /> 134 </div> 135 ); 136 })} 137 </div> 138 ); 139 };