Skip to content

Commit

Permalink
🎨 Add out payloads and format output (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
rogchap authored Jan 11, 2021
1 parent ec48d27 commit a66606a
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 22 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Date picker for `google.protobuf.Timestamp` fields
- Request type icons, in-flight indicator and network out/in count
- Request payloads added to main output to better represent streaming requests
- Output gutter decorations and headers to clearly show separate out/in payloads

### Changed
- Response output control re-architecture to enable future features
- Output control re-architecture to enable future features
- Response tab renamed to "Payload" to reflect both in and out payloads

### Fixed
- A canceled client stream blocks further requests
- Output syntax highlighting on Windows
- Oneof data is sent as empty in some scenarios
- State miss match with descriptor causes `unknown field` error

## [v0.3.3] - 2020-12-13
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/controls/Dropdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
export let labelColor = undefined;
export let removeable = false;
export let Item = undefined;
export let titleProp = "value";
</script>

<style>
Expand Down Expand Up @@ -60,7 +61,7 @@
}
</style>

<div class="dropdown" class:frameless title={selectedValue ? selectedValue.value : ''} >
<div class="dropdown" class:frameless title={selectedValue ? selectedValue[titleProp] : ''} >
{#if label}
<InputLabel on:remove {removeable} {label} {hint} color={labelColor} />
{/if}
Expand Down
52 changes: 52 additions & 0 deletions frontend/src/monaco.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.decor-header {
font-size: 6pt;
color: var(--text-color3);
opacity: 0.6;
}

.decor-empty {
color: var(--text-color2) !important;
font-style: italic;
}

.decor-header.in-payload::before {
content: "\00a0────────── in payload ──────────";
}

.decor-header.out-payload::before {
content: "\00a0────────── out payload ─────────";
}

.decor-lines {
margin-left: 10px;
font-size: var(--font-size);
}

.decor-lines.in-payload::before {
color: var(--green-color);
content: "«";
}

.decor-lines.out-payload::before {
color: var(--yellow-color);
content: "»";
}

.decor-lines.error, .decor-lines-block.error {
margin-left: 12px;
width: 3px !important;
background-color: var(--red-color);
}

.decor-lines-block {
margin-left: 12px;
width: 3px !important;
}

.decor-lines-block.in-payload {
background-color: var(--green-color);
}

.decor-lines-block.out-payload {
background-color: var(--yellow-color);
}
2 changes: 2 additions & 0 deletions frontend/src/monaco.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution";
import "monaco-editor/esm/vs/editor/editor.api";
import "./monaco.css";

monaco.editor.defineTheme("nord-dark", {
base: "vs-dark",
Expand All @@ -10,6 +11,7 @@ monaco.editor.defineTheme("nord-dark", {
{ token: "number", foreground: "#b48ead" },
{ token: "keyword", foreground: "#8fbcbb" },
{ token: "delimiter", foreground: "#88c0d0" },
{ token: "type.identifier", foreground: "#b48ead" }, // enum
],
colors: {
"foreground": "#eceff4",
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/views/FieldOneof.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@
}
const onSelectChanged = ({ detail: { value }}) => {
if (value === selectedValue) {
return
}
if (selectedValue) {
delete state[selectedValue]
state = state;
}
selectedValue = value;
}
const onSelectClear = () => {
if (selectedValue) {
delete state[selectedValue]
state = state;
}
selectedValue = undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/MethodSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</style>

<div class="method-select">
<Dropdown frameless isSearchable items={serviceOptions} selectedValue={serviceSelected} on:select={serviceSelectionChanged} />
<Dropdown frameless isSearchable items={serviceOptions} titleProp="label" selectedValue={serviceSelected} on:select={serviceSelectionChanged} />
<Dropdown frameless isSearchable Item={MethodSelectItem} items={methodOptions} bind:selectedValue={methodSelected} on:select={methodSelectionChanged} />
<div class="spacer" />
<Button
Expand Down
61 changes: 43 additions & 18 deletions frontend/src/views/OutputPane.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,59 @@
inCount = 0;
respModel.setValue("");
hasPayload = false;
})
const append = (payload = "", type = "") => {
let isEmpty = false;
if(payload === "") {
isEmpty = true;
payload = "<empty>\n";
}
const eof = respModel.getLineCount();
const range = new monaco.Range(eof, 0, eof, 0);
respModel.pushEditOperations(null, [{forceMoveMarkers: true, range, text: "\n"+payload }]);
const newEof = respModel.getLineCount();
const payloadStart = new monaco.Range(eof+1, 0, eof+1, 0)
const payloadEnd = new monaco.Range(newEof-1, 0, newEof-1, 0)
const decors = [
{ range, options: { isWholeLine: true, afterContentClassName: "decor-header "+type }},
{ range: payloadStart, options: { isWholeLine: true, linesDecorationsClassName: "decor-lines "+type }},
{ range: payloadEnd, options: { isWholeLine: true, linesDecorationsClassName: "decor-lines "+type }},
];
if (isEmpty) {
decors.push({ range: payloadStart, options: { isWholeLine: true, inlineClassName: "decor-empty" }});
}
if (newEof - eof > 3) {
const payloadMiddle = new monaco.Range(eof+2, 0, newEof-2, 0)
decors.push({ range: payloadMiddle, options: { isWholeLine: true, linesDecorationsClassName: "decor-lines-block "+type }});
}
respModel.deltaDecorations([], decors);
}
wails.Events.On("wombat:in_header_received", data => headers = data)
wails.Events.On("wombat:in_trailer_received", data => trailers = data)
wails.Events.On("wombat:out_payload_received", data => {
append(data, "out-payload");
})
wails.Events.On("wombat:in_payload_received", data => {
hasPayload = true;
const lineCount = respModel.getLineCount();
const lastLineLength = respModel.getLineMaxColumn(lineCount);
const range = new monaco.Range(
lineCount,
lastLineLength,
lineCount,
lastLineLength
);
respModel.pushEditOperations(null, [{forceMoveMarkers: true, range, text: data }]);
append(data, "in-payload");
})
wails.Events.On("wombat:error_received", data => {
append(data, "error");
})
wails.Events.On("wombat:rpc_ended", data => {
rpc = data;
inflight = false;
if (!hasPayload) {
respModel.setValue("<nil>");
}
})
const addStat = (type, data) => {
Expand Down Expand Up @@ -89,7 +114,7 @@
<OutputHeader {rpc} {inflight} {client_stream} {server_stream} {outCount} {inCount} />
<Tabs>
<TabList>
<Tab>Response</Tab>
<Tab>Payload</Tab>
<Tab>Headers/Trailers</Tab>
<Tab>Statistics</Tab>
</TabList>
Expand Down
3 changes: 2 additions & 1 deletion internal/app/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,7 @@ func (a statsHandler) HandleRPC(ctx context.Context, stat stats.RPCStats) {
s.Payload = p
}
a.runtime.Events.Emit(eventStatOutPayload, rpcStatOutPayload{s, fmt.Sprintf("%+v", s.Data)})
a.runtime.Events.Emit(eventOutPayloadReceived, s.Payload)
case *stats.OutTrailer:
a.runtime.Events.Emit(eventStatOutTrailer, rpcStatOutTrailer{s, fmt.Sprintf("%+v", s.Trailer)})
case *stats.InHeader:
Expand Down Expand Up @@ -904,7 +905,7 @@ func (a statsHandler) HandleRPC(ctx context.Context, stat stats.RPCStats) {
a.logger.Errorf("failed to marshal status error to proto text: %v", err)
}
if errProtoStr != "" {
a.runtime.Events.Emit(eventInPayloadReceived, errProtoStr)
a.runtime.Events.Emit(eventErrorReceived, errProtoStr)
}
}
a.runtime.Events.Emit(eventStatEnd, rpcStatEnd{s, errProtoStr})
Expand Down
2 changes: 2 additions & 0 deletions internal/app/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const (
eventMethodInputChanged = "wombat:method_input_changed"
eventRPCStarted = "wombat:rpc_started"
eventRPCEnded = "wombat:rpc_ended"
eventOutPayloadReceived = "wombat:out_payload_received"
eventInPayloadReceived = "wombat:in_payload_received"
eventErrorReceived = "wombat:error_received"
eventInHeaderReceived = "wombat:in_header_received"
eventInTrailerReceived = "wombat:in_trailer_received"
eventStatBegin = "wombat:stat_begin"
Expand Down
5 changes: 5 additions & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ func (s *server) RecordRoute(stream RouteGuide_RecordRouteServer) error {
}
}

// Empty is a empty request/response
func (s *server) Empty(context.Context, *EmptyRequest) (*EmptyResponse, error) {
return &EmptyResponse{}, nil
}

// Serve stats serving a gRPC server that is used for testing
func Serve() {
lis, err := net.Listen("tcp", ":5001")
Expand Down

0 comments on commit a66606a

Please sign in to comment.