Skip to content

Commit

Permalink
feat: add stats
Browse files Browse the repository at this point in the history
  • Loading branch information
hetao92 committed Feb 28, 2022
1 parent 8cde9f5 commit 5025ba6
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 3 deletions.
9 changes: 8 additions & 1 deletion app/config/locale/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,14 @@
"geography(linestring)Format": "Supported data inserting methods: <br /> Call function ST_GeogFromText('LINESTRING()'), for example:ST_GeogFromText('LINESTRING(3 4,10 50,20 25)')",
"geography(polygon)Format": "Supported data inserting methods: <br /> Call function ST_GeogFromText('POLYGON()'), for example:ST_GeogFromText('POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))')",
"durationFormat": "Supported data inserting methods: <br /> Call function duration(<map>), for example:duration({years: 1, seconds: 0})",
"setTTL": "Set TTL (Time To Live)"
"setTTL": "Set TTL (Time To Live)",
"refresh": "Refresh",
"lastRefreshTime": "Last refreshed time",
"statsType": "Type",
"statsName": "Name",
"statsCount": "Count",
"statError": "Update Failed, Please try again.",
"statFinished": "Statistics end"
},
"menu": {
"use": "Use Manual",
Expand Down
9 changes: 8 additions & 1 deletion app/config/locale/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,14 @@
"geography(linestring)Format": "geo(linestring) 类型支持插入方式: <br /> 调用函数 ST_GeogFromText('LINESTRING()'),例如:ST_GeogFromText('LINESTRING(3 4,10 50,20 25)')",
"geography(polygon)Format": "geo(polygon) 类型支持插入方式: <br /> 调用函数 ST_GeogFromText('POLYGON()'),例如:ST_GeogFromText('POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))')",
"durationFormat": "duration 类型支持插入方式: <br /> 调用函数 duration(<map>),例如:duration({years: 1, seconds: 0})",
"setTTL": "设置TTL(存活时间)"
"setTTL": "设置TTL(存活时间)",
"refresh": "更新",
"lastRefreshTime": "上次更新时间",
"statsType": "维度",
"statsName": "名称",
"statsCount": "数量",
"statError": "统计失败,请重试",
"statFinished": "统计结束"
},
"menu": {
"use": "使用手册",
Expand Down
2 changes: 1 addition & 1 deletion app/pages/Schema/SchemaConfig/List/Index/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Popconfirm, Radio, Table, message } from 'antd';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import intl from 'react-intl-universal';
import { Link, useHistory, useParams } from 'react-router-dom';
import { useHistory, useParams } from 'react-router-dom';
import Icon from '@app/components/Icon';
import { observer } from 'mobx-react-lite';
import { useStore } from '@app/stores';
Expand Down
20 changes: 20 additions & 0 deletions app/pages/Schema/SchemaConfig/List/SpaceStats/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@import '~@app/common.less';
.nebula-stats {
.operations {
margin: 20px 0 17px;
display: flex;
align-items: center;
font-size: 14px;
.ant-btn {
width: 110px;
}
.label {
margin-left: 30px;
color: @darkGray;
}
.label::after {
content: ": ";
padding-right: 5px;
}
}
}
125 changes: 125 additions & 0 deletions app/pages/Schema/SchemaConfig/List/SpaceStats/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Button, Table, message } from 'antd';
import dayjs from 'dayjs';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import intl from 'react-intl-universal';
import { useParams } from 'react-router-dom';
import { observer } from 'mobx-react-lite';
import { useStore } from '@app/stores';
import { IJobStatus } from '@app/interfaces/schema';
import { trackPageView } from '@app/utils/stat';
import Cookie from 'js-cookie';

import './index.less';

const SpaceStats = () => {
const timer = useRef<NodeJS.Timeout | null>(null);
const { schema: { getJobStatus, submitStats, getStats } } = useStore();
const { space } = useParams() as { space :string };
const [data, setData] = useState([]);
const [updateTime, setUpdateTime] = useState('');
const [jobId, setJobId] = useState<any>(null);
const [loading, setLoading] = useState(false);
const columns = useMemo(() => [
{
title: intl.get('schema.statsType'),
dataIndex: 'Type',
},
{
title: intl.get('schema.statsName'),
dataIndex: 'Name',
},
{
title: intl.get('schema.statsCount'),
dataIndex: 'Count',
},
], [Cookie.get('lang')]);
useEffect(() => {
trackPageView('/space/stats');
initData();
getJobs();
return () => {
timer.current && clearTimeout(timer.current);
};
}, [space]);

const initData = () => {
setJobId(null);
setUpdateTime('');
setData([]);
};

const getData = async() => {
const { code, data } = await getStats();
if (code === 0) {
setData(data.tables);
}
};

const getJobs = async() => {
const { code, data } = await getJobStatus();
if (code === 0) {
const stat = data.tables.filter(item => item.Command === 'STATS')[0];
if (stat?.Status === IJobStatus.finished) {
getData();
setUpdateTime(stat['Stop Time']);
} else if (stat) {
const jobId = stat['Job Id'];
setJobId(jobId);
getStatStatus(jobId);
}
}
};

const getStatStatus = async id => {
const { code, data } = await getJobStatus(id);
if (code === 0) {
const job = data.tables[0];
if (job.Status === IJobStatus.finished) {
getData();
setUpdateTime(job['Stop Time']);
setJobId(null);
message.success(intl.get('schema.statFinished'));
} else if ([IJobStatus.running, IJobStatus.queue].includes(job.Status)) {
timer.current = setTimeout(() => getStatStatus(id), 2000);
} else if (job.Status === 'FAILED') {
message.warning(intl.get('schema.statError'));
setJobId(null);
}
}
};
const handleSubmitStats = async() => {
setLoading(true);
const { code, data } = await submitStats();
setLoading(false);
if (code === 0) {
const id = data.tables[0]['New Job Id'];
setJobId(id);
await getStatStatus(id);
}
};
return (
<div className="nebula-stats">
<div className="operations">
<Button
type="primary"
onClick={handleSubmitStats}
loading={loading || jobId !== null}
>
{intl.get('schema.refresh')}
</Button>
<span className="label">{intl.get('schema.lastRefreshTime')}</span>
<span>
{updateTime ? dayjs(updateTime).format('YYYY-MM-DD HH:mm:ss') : null}
</span>
</div>
<Table
className="expanded-table"
dataSource={data}
columns={columns}
rowKey="Name"
/>
</div>
);
};

export default observer(SpaceStats);
6 changes: 6 additions & 0 deletions app/pages/Schema/SchemaConfig/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Breadcrumb from '@app/components/Breadcrumb';
import TagList from './List/Tag';
import EdgeList from './List/Edge';
import IndexList from './List/Index/index';
import SpaceStats from './List/SpaceStats';
import CommonCreate from './Create/CommonCreate';
import IndexCreate from './Create/IndexCreate';
import CommonEdit from './Edit/CommonEdit';
Expand Down Expand Up @@ -113,6 +114,11 @@ const SchemaConfig = () => {
exact={true}
component={IndexList}
/>
<Route
path="/schema/:space/statistic/list"
exact={true}
component={SpaceStats}
/>
<Route
path={`/schema/:space/tag/create`}
exact={true}
Expand Down
34 changes: 34 additions & 0 deletions app/stores/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,40 @@ export class SchemaStore {
return null;
}

// stats
submitStats = async() => {
const { code, data } = (await service.execNGQL(
{
gql: `
SUBMIT JOB STATS
`,
},
{
trackEventConfig: {
category: 'schema',
action: 'submit_stats',
},
},
)) as any;
return { code, data };
}

getStats = async() => {
const { code, data } = (await service.execNGQL({
gql: `
SHOW STATS
`,
})) as any;
return { code, data };
}

getJobStatus = async(id?) => {
const gql = id === undefined ? 'SHOW JOBS' : `SHOW JOB ${id}`;
const { code, data } = (await service.execNGQL({
gql,
})) as any;
return { code, data };
}
}

const schemaStore = new SchemaStore();
Expand Down

0 comments on commit 5025ba6

Please sign in to comment.