Skip to content

Commit

Permalink
server, ui: use POST request method for HotRangesV2 service
Browse files Browse the repository at this point in the history
Initially, `HotRangesV2` service in status server was defined
to use GET method to handle HTTP request. It was convenient way
to display response data in Advanced debugging page since it allowed
to render response body right on to page.

But now, hot ranges will be used on user facing page and request
dispatching for hot ranges api should follow generic workflow:
initialize `HotRangesRequest` protobuf message and dispatch request
with `src/util/api` service. This restriction forces to use POST
method (since GET method doesn't allow to provide request body).

In addition, Hot Ranges debugging page is refactored to use `api`
service.

Release note: None
  • Loading branch information
koorosh committed Jan 18, 2022
1 parent b5d24f0 commit 2149fcf
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/generated/http/full.md
Original file line number Diff line number Diff line change
Expand Up @@ -3098,7 +3098,7 @@ target node(s) selected in a HotRangesRequest.

## HotRangesV2

`GET /_status/v2/hotranges`
`POST /_status/v2/hotranges`



Expand Down
22 changes: 10 additions & 12 deletions pkg/server/serverpb/status.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pkg/server/serverpb/status.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1744,7 +1744,8 @@ service Status {

rpc HotRangesV2(HotRangesRequest) returns (HotRangesResponseV2) {
option (google.api.http) = {
get : "/_status/v2/hotranges"
post : "/_status/v2/hotranges"
body : "*"
};
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/server/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ func TestHotRanges2Response(t *testing.T) {
defer ts.Stopper().Stop(context.Background())

var hotRangesResp serverpb.HotRangesResponseV2
if err := getStatusJSONProto(ts, "v2/hotranges", &hotRangesResp); err != nil {
if err := postStatusJSONProto(ts, "v2/hotranges", &serverpb.HotRangesRequest{}, &hotRangesResp); err != nil {
t.Fatal(err)
}
if len(hotRangesResp.Ranges) == 0 {
Expand Down
7 changes: 7 additions & 0 deletions pkg/ui/workspaces/db-console/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import Nodes from "src/views/reports/containers/nodes";
import ProblemRanges from "src/views/reports/containers/problemRanges";
import Range from "src/views/reports/containers/range";
import ReduxDebug from "src/views/reports/containers/redux";
import HotRanges from "src/views/reports/containers/hotranges";
import Settings from "src/views/reports/containers/settings";
import Stores from "src/views/reports/containers/stores";
import SQLActivityPage from "src/views/sqlActivity/sqlActivityPage";
Expand Down Expand Up @@ -274,6 +275,12 @@ export const App: React.FC<AppProps> = (props: AppProps) => {
path="/debug/enqueue_range"
component={EnqueueRange}
/>
<Route exact path="/debug/hotranges" component={HotRanges} />
<Route
exact
path="/debug/hotranges/:node_id"
component={HotRanges}
/>

<Route path="/raft">
<Raft>
Expand Down
15 changes: 15 additions & 0 deletions pkg/ui/workspaces/db-console/src/util/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ export type ResetSQLStatsResponseMessage = protos.cockroach.server.serverpb.Rese
export type ResetIndexUsageStatsRequestMessage = protos.cockroach.server.serverpb.ResetIndexUsageStatsRequest;
export type ResetIndexUsageStatsResponseMessage = protos.cockroach.server.serverpb.ResetIndexUsageStatsResponse;

export type HotRangesRequestMessage = protos.cockroach.server.serverpb.HotRangesRequest;
export type HotRangesV2ResponseMessage = protos.cockroach.server.serverpb.HotRangesResponseV2;

// API constants

export const API_PREFIX = "_admin/v1";
Expand Down Expand Up @@ -791,3 +794,15 @@ export function resetIndexUsageStats(
timeout,
);
}

export function getHotRanges(
req: HotRangesRequestMessage,
timeout?: moment.Duration,
): Promise<HotRangesV2ResponseMessage> {
return timeoutFetch(
serverpb.HotRangesResponseV2,
`${STATUS_PREFIX}/v2/hotranges`,
req as any,
timeout,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -417,13 +417,13 @@ export default function Debug() {
<DebugTableRow title="Hot Ranges">
<DebugTableLink
name="All Nodes"
url="_status/v2/hotranges"
note="_status/v2/hotranges"
url="#/debug/hotranges"
note="#/debug/hotranges"
/>
<DebugTableLink
name="Single node's ranges"
url="_status/v2/hotranges?node_id=local"
note="_status/v2/hotranges?node_id=[node_id]"
url="#/debug/hotranges/local"
note="#/debug/hotranges/[node_id]"
/>
</DebugTableRow>
<DebugTableRow title="Single Node Specific">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2022 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

import React, { useCallback, useEffect, useState } from "react";
import { RouteComponentProps, withRouter } from "react-router-dom";
import moment from "moment";
import { Button } from "@cockroachlabs/ui-components";
import { cockroach } from "src/js/protos";
import { getHotRanges } from "src/util/api";

type HotRangesProps = RouteComponentProps<{ node_id: string }>;

const HotRanges = (props: HotRangesProps) => {
const nodeIdParam = props.match.params["node_id"];
const [nodeId, setNodeId] = useState(nodeIdParam);
const [time, setTime] = useState<moment.Moment>(moment());
const [hotRanges, setHotRanges] = useState<
cockroach.server.serverpb.HotRangesResponseV2["ranges"]
>([]);
const requestHotRanges = useCallback(() => {
const request = cockroach.server.serverpb.HotRangesRequest.create({
node_id: nodeId,
});
getHotRanges(request).then(response => {
setHotRanges(response.ranges);
setTime(moment());
});
}, [nodeId]);
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(requestHotRanges, [nodeId]);
useEffect(() => {
setNodeId(nodeIdParam);
}, [nodeIdParam]);
return (
<div
style={{
display: "flex",
flexDirection: "column",
}}
>
<span>{`Node ID: ${nodeId ?? "All nodes"}`}</span>
<span>{`Time: ${time.toISOString()}`}</span>
<Button onClick={requestHotRanges} intent={"secondary"}>
Refresh
</Button>
<pre className="state-json-box">{JSON.stringify(hotRanges, null, 2)}</pre>
</div>
);
};

export default withRouter(HotRanges);

0 comments on commit 2149fcf

Please sign in to comment.