Even more runtime debugger and docs fixes

This commit is contained in:
Frikky
2023-12-03 01:42:03 +01:00
parent dee1ee48f8
commit ec726fe073
6 changed files with 115 additions and 38 deletions
+1
View File
@@ -522,6 +522,7 @@ class AppBase:
break break
else: else:
self.logger.info(f"[ERROR] Bad resp {ret.status_code}: {ret.text}") self.logger.info(f"[ERROR] Bad resp {ret.status_code}: {ret.text}")
time.sleep(sleeptime)
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
self.logger.info(f"[DEBUG] Request problem: {e}") self.logger.info(f"[DEBUG] Request problem: {e}")
+1 -1
View File
@@ -18,7 +18,7 @@ require (
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/h2non/filetype v1.1.3 github.com/h2non/filetype v1.1.3
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.5.11 github.com/shuffle/shuffle-shared v0.5.14
golang.org/x/crypto v0.14.0 golang.org/x/crypto v0.14.0
google.golang.org/api v0.125.0 google.golang.org/api v0.125.0
google.golang.org/grpc v1.55.0 google.golang.org/grpc v1.55.0
+4
View File
@@ -416,6 +416,10 @@ github.com/shuffle/shuffle-shared v0.4.97 h1:1c8LdNteMykKNEV97vwP63oSP2tV/Uso3O4
github.com/shuffle/shuffle-shared v0.4.97/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI= github.com/shuffle/shuffle-shared v0.4.97/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
github.com/shuffle/shuffle-shared v0.4.98 h1:pgsLdWUpxZ/q+eHpAjOCH9icOsmuO5u2olmirOldy5A= github.com/shuffle/shuffle-shared v0.4.98 h1:pgsLdWUpxZ/q+eHpAjOCH9icOsmuO5u2olmirOldy5A=
github.com/shuffle/shuffle-shared v0.4.98/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI= github.com/shuffle/shuffle-shared v0.4.98/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
github.com/shuffle/shuffle-shared v0.5.11 h1:Eqbs9o8E49QAL5/6aV6BfFtWSjLIvgET7AL3fa4OQTg=
github.com/shuffle/shuffle-shared v0.5.11/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
github.com/shuffle/shuffle-shared v0.5.14 h1:d14u1e4k+qKgnf4Insq4x2S+0MMKlDqdyTTyVP3puRA=
github.com/shuffle/shuffle-shared v0.5.14/go.mod h1:X613gbo0dT3fnYvXDRwjQZyLC+T49T2nSQOrCV5QMlI=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
+67 -4
View File
@@ -56,6 +56,7 @@ const RuntimeDebugger = (props) => {
const [startTime, setStartTime] = useState("") const [startTime, setStartTime] = useState("")
const [workflow, setWorkflow] = useState({}) const [workflow, setWorkflow] = useState({})
const [ignoreOrg, setIgnoreOrg] = useState(false)
const [searchLoading, setSearchLoading] = useState(false) const [searchLoading, setSearchLoading] = useState(false)
const [rowCursor, setCursor] = useState("") const [rowCursor, setCursor] = useState("")
const [rowsPerPage, setRowsPerPage] = useState(10) const [rowsPerPage, setRowsPerPage] = useState(10)
@@ -85,6 +86,7 @@ const RuntimeDebugger = (props) => {
status: status.toUpperCase(), status: status.toUpperCase(),
start_time: startTime, start_time: startTime,
end_time: endTime, end_time: endTime,
ignore_org: ignoreOrg,
} }
fetch(`${globalUrl}/api/v1/workflows/search`, { fetch(`${globalUrl}/api/v1/workflows/search`, {
@@ -185,6 +187,38 @@ const RuntimeDebugger = (props) => {
} }
}, []) }, [])
const forceContinue = (execution) => {
console.log(`FORCE CONTINUE execution ${execution.execution_id} for workflow ${execution.workflow.id}`)
fetch(`${globalUrl}/api/v1/workflows/${execution.workflow.id}/executions/${execution.execution_id}/rerun`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
if (data.reason !== undefined && data.reason !== null && data.reason !== "") {
toast("Successful response: " + data.reason)
} else {
toast("Successfully forced continue")
}
} else {
if (data.reason !== undefined && data.reason !== null && data.reason !== "") {
toast(`Failed to force continue: ${data.reason}`)
} else {
toast("Failed to force continue")
}
}
})
.catch((error) => {
console.error("Error:", error);
toast(`Failed to force continue: ${error}`)
})
}
const imageSize = 30 const imageSize = 30
const timenowUnix = Math.floor(Date.now() / 1000) const timenowUnix = Math.floor(Date.now() / 1000)
const columns: GridColDef[] = [ const columns: GridColDef[] = [
@@ -371,7 +405,7 @@ const RuntimeDebugger = (props) => {
{ {
field: 'id', field: 'id',
headerName: 'Explore', headerName: 'Explore',
width: 100, width: 120,
renderCell: (params) => { renderCell: (params) => {
const parsedResult = params.row.result === null || params.row.result === undefined || params.row.result === "" ? "" : params.row.result const parsedResult = params.row.result === null || params.row.result === undefined || params.row.result === "" ? "" : params.row.result
@@ -443,6 +477,7 @@ const RuntimeDebugger = (props) => {
} }
return ( return (
<div style={{display: "flex", }}>
<Tooltip arrow placement="right" title={ <Tooltip arrow placement="right" title={
<Typography variant="body2" style={{whiteSpace: "pre-line", padding: 10, }}> <Typography variant="body2" style={{whiteSpace: "pre-line", padding: 10, }}>
Workflow result: {errorReason}<br/><br/> Workflow result: {errorReason}<br/><br/>
@@ -457,8 +492,23 @@ const RuntimeDebugger = (props) => {
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer"> <Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
<OpenInNewIcon fontSize="small" style={{marginTop: 7, }} /> <OpenInNewIcon fontSize="small" style={{marginTop: 7, }} />
</Link> </Link>
</span>
</Tooltip>
<Tooltip arrow title="Force continue workflow. Only workflows for workflows in EXECUTING state. This is NOT a rerun, but way for Shuffle to figure out the next steps automatically. If the execution doesn't finish even after trying this, please contact support@shuffler.io">
<IconButton <IconButton
style={{marginLeft: 10, }} style={{marginLeft: 5, }}
disabled={params.row.status !== "EXECUTING"}
onClick={() => {
forceContinue(params.row)
}}
>
<PlayArrowIcon fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip arrow title="Explore workflow run logs">
<IconButton
style={{marginLeft: 5, }}
onClick={() => { onClick={() => {
window.open(`${globalUrl}/api/v1/workflows/search/${params.row.id}`, "_blank") window.open(`${globalUrl}/api/v1/workflows/search/${params.row.id}`, "_blank")
}} }}
@@ -466,8 +516,8 @@ const RuntimeDebugger = (props) => {
> >
<InsightsIcon fontSize="small" /> <InsightsIcon fontSize="small" />
</IconButton> </IconButton>
</span>
</Tooltip> </Tooltip>
</div>
) )
} }
}, },
@@ -632,6 +682,19 @@ const RuntimeDebugger = (props) => {
</ButtonGroup> </ButtonGroup>
: null} : null}
{userdata.support === true ?
<Button
variant={ignoreOrg ? "contained" : "outlined"}
color="primary"
style={{maxHeight: 40, marginTop: 25, }}
onClick={() => {
setIgnoreOrg(!ignoreOrg)
}}
>
{ignoreOrg ? "Ignoring Org" : "Ignore Org"}
</Button>
: null}
</div> </div>
<form onSubmit={(e) => { <form onSubmit={(e) => {
submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage) submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage)
@@ -799,7 +862,7 @@ const RuntimeDebugger = (props) => {
</LocalizationProvider> </LocalizationProvider>
<Button <Button
variant="contained" variant="outlined"
color="primary" color="primary"
onClick={() => { onClick={() => {
submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage) submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage)
+10 -5
View File
@@ -1043,16 +1043,16 @@ const AngularWorkflow = (defaultprops) => {
execution_id: tmpView, execution_id: tmpView,
//authorization: data.authorization, //authorization: data.authorization,
} }
setExecutionRunning(true);
setExecutionModalView(1); setExecutionModalView(1);
setExecutionRequest(cur_execution); setExecutionRequest(cur_execution);
start(); start();
//const newitem = removeParam("execution_id", cursearch); //const newitem = removeParam("execution_id", cursearch);
//navigate(curpath + newitem) //navigate(curpath + newitem)
//setTimeout(() => {
setTimeout(() => { // stop()
stop() //}, 5000);
}, 5000);
} }
} }
} else { } else {
@@ -15114,7 +15114,10 @@ const AngularWorkflow = (defaultprops) => {
marginTop: "auto", marginTop: "auto",
marginBottom: "auto", marginBottom: "auto",
}} }}
onClick={() => { }} onClick={() => {
setExecutionRunning(false);
stop()
}}
> >
<ArrowBackIcon style={{ color: "rgba(255,255,255,0.5)" }} /> <ArrowBackIcon style={{ color: "rgba(255,255,255,0.5)" }} />
</IconButton> </IconButton>
@@ -15124,6 +15127,8 @@ const AngularWorkflow = (defaultprops) => {
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search; const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const newitem = removeParam("execution_id", cursearch); const newitem = removeParam("execution_id", cursearch);
navigate(curpath + newitem) navigate(curpath + newitem)
setExecutionRunning(false);
stop()
}} }}
> >
See more runs See more runs
+9 -5
View File
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { toast } from 'react-toastify';
import Markdown from 'react-markdown' import Markdown from 'react-markdown'
import { BrowserView, MobileView } from "react-device-detect"; import { BrowserView, MobileView } from "react-device-detect";
@@ -135,7 +136,7 @@ const Docs = (defaultprops) => {
}; };
const fetchDocList = () => { const fetchDocList = () => {
fetch(globalUrl + "/api/v1/docs", { fetch(`${globalUrl}/api/v1/docs`, {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -147,9 +148,8 @@ const Docs = (defaultprops) => {
if (responseJson.success) { if (responseJson.success) {
setList(responseJson.list); setList(responseJson.list);
} else { } else {
setList([ setList(["# Error loading documentation. Please contact us if this persists.",]);
"# Error loading documentation. Please contact us if this persists.", toast("Failed loading documentation. Please reload the window")
]);
} }
setListLoaded(true); setListLoaded(true);
}) })
@@ -157,7 +157,7 @@ const Docs = (defaultprops) => {
}; };
const fetchDocs = (docId) => { const fetchDocs = (docId) => {
fetch(globalUrl + "/api/v1/docs/" + docId, { fetch(`${globalUrl}/api/v1/docs/${docId}`, {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -166,6 +166,10 @@ const Docs = (defaultprops) => {
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((responseJson) => { .then((responseJson) => {
if (responseJson.success === false) {
//toast("Failed loading documentation. Please reload the UI")
}
if (responseJson.success && responseJson.reason !== undefined) { if (responseJson.success && responseJson.reason !== undefined) {
// Find <img> tags and translate them into ![]() format // Find <img> tags and translate them into ![]() format
const imgRegex = /<img.*?src="(.*?)"/g; const imgRegex = /<img.*?src="(.*?)"/g;