mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-07-04 03:48:58 +00:00
Fix the selected entry behavior by propagating the focusedEntryId
through WebSocket (before #452) TRA-3983 (#513)
* Revert the select entry behavior into its original state RACING! (before #452) [TRA-3983 alternative 3] * Remove the remaining `forceSelect`(s) * Add a missing `focusedEntryId` prop * Fix the race condition * Propagate the `focusedEntryId` through WebSocket to prevent racing
This commit is contained in:
parent
9696ad9bad
commit
873f252544
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"mizuserver/pkg/models"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -94,6 +95,8 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
||||
startTimeBytes, _ := models.CreateWebsocketStartTimeMessage(startTime)
|
||||
SendToSocket(socketId, startTimeBytes)
|
||||
|
||||
queryRecieved := false
|
||||
|
||||
for {
|
||||
_, msg, err := ws.ReadMessage()
|
||||
if err != nil {
|
||||
@ -101,7 +104,9 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
||||
break
|
||||
}
|
||||
|
||||
if !queryRecieved {
|
||||
if !isTapper && !isQuerySet {
|
||||
queryRecieved = true
|
||||
query := string(msg)
|
||||
err = basenine.Validate(shared.BasenineHost, shared.BaseninePort, query)
|
||||
if err != nil {
|
||||
@ -161,6 +166,14 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
||||
} else {
|
||||
eventHandlers.WebSocketMessage(socketId, msg)
|
||||
}
|
||||
} else {
|
||||
id, err := strconv.Atoi(string(msg))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
focusEntryBytes, _ := models.CreateWebsocketFocusEntry(id)
|
||||
SendToSocket(socketId, focusEntryBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,11 @@ type WebSocketStartTimeMessage struct {
|
||||
Data int64 `json:"data"`
|
||||
}
|
||||
|
||||
type WebSocketFocusEntryMessage struct {
|
||||
*shared.WebSocketMessageMetadata
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
func CreateBaseEntryWebSocketMessage(base map[string]interface{}) ([]byte, error) {
|
||||
message := &WebSocketEntryMessage{
|
||||
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
|
||||
@ -117,6 +122,16 @@ func CreateWebsocketStartTimeMessage(base int64) ([]byte, error) {
|
||||
return json.Marshal(message)
|
||||
}
|
||||
|
||||
func CreateWebsocketFocusEntry(id int) ([]byte, error) {
|
||||
message := &WebSocketFocusEntryMessage{
|
||||
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
|
||||
MessageType: shared.WebSocketMessageFocusEntry,
|
||||
},
|
||||
Id: id,
|
||||
}
|
||||
return json.Marshal(message)
|
||||
}
|
||||
|
||||
// ExtendedHAR is the top level object of a HAR log.
|
||||
type ExtendedHAR struct {
|
||||
Log *ExtendedLog `json:"log"`
|
||||
|
@ -1,11 +1,12 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/op/go-logging"
|
||||
"github.com/up9inc/mizu/shared/logger"
|
||||
"github.com/up9inc/mizu/tap/api"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@ -21,6 +22,7 @@ const (
|
||||
WebSocketMessageTypeToast WebSocketMessageType = "toast"
|
||||
WebSocketMessageTypeQueryMetadata WebSocketMessageType = "queryMetadata"
|
||||
WebSocketMessageTypeStartTime WebSocketMessageType = "startTime"
|
||||
WebSocketMessageFocusEntry WebSocketMessageType = "focusEntry"
|
||||
)
|
||||
|
||||
type Resources struct {
|
||||
|
@ -69,10 +69,10 @@ const EntrySummary: React.FC<any> = ({data, updateQuery}) => {
|
||||
return <EntryItem
|
||||
key={entry.id}
|
||||
entry={entry}
|
||||
focusedEntryId={null}
|
||||
setFocusedEntryId={null}
|
||||
style={{}}
|
||||
updateQuery={updateQuery}
|
||||
forceSelect={false}
|
||||
headingMode={true}
|
||||
/>;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, {useState} from "react";
|
||||
import React from "react";
|
||||
import styles from './EntryListItem.module.sass';
|
||||
import StatusCode, {getClassification, StatusCodeClassification} from "../UI/StatusCode";
|
||||
import Protocol, {ProtocolInterface} from "../UI/Protocol"
|
||||
@ -37,16 +37,16 @@ interface Rules {
|
||||
|
||||
interface EntryProps {
|
||||
entry: Entry;
|
||||
focusedEntryId: string;
|
||||
setFocusedEntryId: (id: string) => void;
|
||||
style: object;
|
||||
updateQuery: any;
|
||||
forceSelect: boolean;
|
||||
headingMode: boolean;
|
||||
}
|
||||
|
||||
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, style, updateQuery, forceSelect, headingMode}) => {
|
||||
export const EntryItem: React.FC<EntryProps> = ({entry, focusedEntryId, setFocusedEntryId, style, updateQuery, headingMode}) => {
|
||||
|
||||
const [isSelected, setIsSelected] = useState(!forceSelect ? false : true);
|
||||
const isSelected = focusedEntryId === entry.id.toString();
|
||||
|
||||
const classification = getClassification(entry.statusCode)
|
||||
const numberOfRules = entry.rules.numberOfRules
|
||||
@ -125,7 +125,6 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, style
|
||||
${isSelected && !rule && !contractEnabled ? styles.rowSelected : additionalRulesProperties}`}
|
||||
onClick={() => {
|
||||
if (!setFocusedEntryId) return;
|
||||
setIsSelected(!isSelected);
|
||||
setFocusedEntryId(entry.id.toString());
|
||||
}}
|
||||
style={{
|
||||
|
@ -119,20 +119,20 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
|
||||
switch (message.messageType) {
|
||||
case "entry":
|
||||
const entry = message.data;
|
||||
var forceSelect = false;
|
||||
var focusThis = false;
|
||||
if (!focusedEntryId) {
|
||||
focusThis = true;
|
||||
setFocusedEntryId(entry.id.toString());
|
||||
forceSelect = true;
|
||||
}
|
||||
setEntriesBuffer([
|
||||
...entriesBuffer,
|
||||
<EntryItem
|
||||
key={entry.id}
|
||||
entry={entry}
|
||||
focusedEntryId={focusThis ? entry.id.toString() : focusedEntryId}
|
||||
setFocusedEntryId={setFocusedEntryId}
|
||||
style={{}}
|
||||
updateQuery={updateQuery}
|
||||
forceSelect={forceSelect}
|
||||
headingMode={false}
|
||||
/>
|
||||
]);
|
||||
@ -166,6 +166,16 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
|
||||
case "startTime":
|
||||
setStartTime(message.data);
|
||||
break;
|
||||
case "focusEntry":
|
||||
// To achieve selecting only one entry, render all elements in the buffer
|
||||
// with the current `focusedEntryId` value.
|
||||
entriesBuffer.forEach((entry: any, i: number) => {
|
||||
entriesBuffer[i] = React.cloneElement(entry, {
|
||||
focusedEntryId: focusedEntryId
|
||||
});
|
||||
})
|
||||
setEntries(entriesBuffer);
|
||||
break;
|
||||
default:
|
||||
console.error(`unsupported websocket message type, Got: ${message.messageType}`)
|
||||
}
|
||||
@ -191,6 +201,11 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
|
||||
useEffect(() => {
|
||||
if (!focusedEntryId) return;
|
||||
setSelectedEntryData(null);
|
||||
|
||||
if (ws.current.readyState === WebSocket.OPEN) {
|
||||
ws.current.send(focusedEntryId);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const entryData = await api.getEntry(focusedEntryId);
|
||||
|
Loading…
Reference in New Issue
Block a user