Skip to content

Commit

Permalink
Merge pull request #225 from flatironinstitute/feature/194-disable-co…
Browse files Browse the repository at this point in the history
…mpile-button-no-connection

Disable compile buttons if no server connection
  • Loading branch information
WardBrian authored Oct 8, 2024
2 parents 971cd3a + 401865e commit b0f9fd2
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 103 deletions.
2 changes: 1 addition & 1 deletion gui/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CompileContextProvider } from "@SpCompilation/CompileContextProvider";
import ToggleableThemeProvider from "./ToggleableThemeProvider";
import ProjectContextProvider from "@SpCore/ProjectContextProvider";
import HomePage from "@SpPages/HomePage";
import { Analytics } from "@vercel/analytics/react";
import { BrowserRouter } from "react-router-dom";
import { CompileContextProvider } from "./CompileContext/CompileContextProvider";

const App = () => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type CompileContextType = {
setValidSyntax: (valid: boolean) => void;
stanWasmServerUrl: string;
setStanWasmServerUrl: (url: string) => void;
isConnected: boolean;
retryConnection: () => void;
};

export const CompileContext = createContext<CompileContextType>({
Expand All @@ -26,4 +28,6 @@ export const CompileContext = createContext<CompileContextType>({
setValidSyntax: () => {},
stanWasmServerUrl: "",
setStanWasmServerUrl: () => {},
isConnected: false,
retryConnection: () => {},
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ProjectContext } from "@SpCore/ProjectContextProvider";
import compileStanProgram from "@SpCompileContext/compileStanProgram";
import {
FunctionComponent,
PropsWithChildren,
Expand All @@ -8,13 +7,42 @@ import {
useEffect,
useState,
} from "react";
import { CompileContext, CompileStatus } from "./CompileContext";
import { publicCompilationServerUrl } from "@SpStanc/CompilationServerConnectionControl";
import { CompileContext, CompileStatus } from "@SpCompilation/CompileContext";
import { publicCompilationServerUrl } from "@SpCompilation/Constants";
import compileStanProgram from "./compileStanProgram";

type CompileContextProviderProps = {
// none
};

const useIsConnected = (stanWasmServerUrl: string) => {
const probeUrl = `${stanWasmServerUrl}/probe`;
const [isConnected, setIsConnected] = useState<boolean>(false);
const [retryCode, setRetryCode] = useState<number>(0);
const retryConnection = useCallback(() => {
setRetryCode((r) => r + 1);
}, []);
useEffect(() => {
setIsConnected(false);
if (!probeUrl.startsWith("http://") && !probeUrl.startsWith("https://")) {
// important to do this check because otherwise fetch may succeed because
// the server of this web app may respond with success
return;
}
(async () => {
try {
const response = await fetch(probeUrl);
if (response.status === 200) {
setIsConnected(true);
}
} catch (err) {
setIsConnected(false);
}
})();
}, [probeUrl, retryCode]);
return { isConnected, retryConnection };
};

const initialStanWasmServerUrl =
localStorage.getItem("stanWasmServerUrl") || publicCompilationServerUrl;

Expand Down Expand Up @@ -83,6 +111,8 @@ export const CompileContextProvider: FunctionComponent<
stanWasmServerUrl,
]);

const { isConnected, retryConnection } = useIsConnected(stanWasmServerUrl);

return (
<CompileContext.Provider
value={{
Expand All @@ -94,6 +124,8 @@ export const CompileContextProvider: FunctionComponent<
setValidSyntax,
stanWasmServerUrl,
setStanWasmServerUrl,
isConnected,
retryConnection,
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CompileContext } from "@SpCompileContext/CompileContext";
import { CompileContext } from "@SpCompilation/CompileContext";
import { Refresh } from "@mui/icons-material";
import Divider from "@mui/material/Divider";
import FormControl from "@mui/material/FormControl";
Expand All @@ -10,11 +10,11 @@ import RadioGroup from "@mui/material/RadioGroup";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { FunctionComponent, useCallback, useContext } from "react";
import { serverTypeForUrl } from "./CompilationServerToolbar";
import {
localCompilationServerUrl,
publicCompilationServerUrl,
serverTypeForUrl,
} from "./CompilationServerConnectionControl";
} from "./Constants";

type ConfigureCompilationServerDialogProps = {
isConnected: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,16 @@ import { Cancel, Check } from "@mui/icons-material";
import CloseableDialog, {
useDialogControls,
} from "@SpComponents/CloseableDialog";
import {
FunctionComponent,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import ConfigureCompilationServerDialog from "./ConfigureCompilationServerDialog";
import { FunctionComponent, useCallback, useContext } from "react";
import ConfigureCompilationServerDialog from "./CompilationServerDialog";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import { CompileContext } from "@SpCompileContext/CompileContext";

export const publicCompilationServerUrl =
"https://stan-wasm.flatironinstitute.org";
export const localCompilationServerUrl = "http://localhost:8083";

type ServerType = "public" | "local" | "custom";
import { CompileContext } from "@SpCompilation/CompileContext";
import {
ServerType,
publicCompilationServerUrl,
localCompilationServerUrl,
} from "./Constants";

type CompilationServerConnectionControlProps = {
// none
Expand All @@ -28,8 +21,8 @@ type CompilationServerConnectionControlProps = {
const CompilationServerConnectionControl: FunctionComponent<
CompilationServerConnectionControlProps
> = () => {
const { stanWasmServerUrl } = useContext(CompileContext);
const { isConnected, retryConnection } = useIsConnected(stanWasmServerUrl);
const { stanWasmServerUrl, isConnected, retryConnection } =
useContext(CompileContext);

const {
handleOpen: openDialog,
Expand Down Expand Up @@ -80,32 +73,4 @@ export const serverTypeForUrl = (url: string): ServerType => {
: "custom";
};

const useIsConnected = (stanWasmServerUrl: string) => {
const probeUrl = `${stanWasmServerUrl}/probe`;
const [isConnected, setIsConnected] = useState<boolean>(false);
const [retryCode, setRetryCode] = useState<number>(0);
const retryConnection = useCallback(() => {
setRetryCode((r) => r + 1);
}, []);
useEffect(() => {
setIsConnected(false);
if (!probeUrl.startsWith("http://") && !probeUrl.startsWith("https://")) {
// important to do this check because otherwise fetch may succeed because
// the server of this web app may respond with success
return;
}
(async () => {
try {
const response = await fetch(probeUrl);
if (response.status === 200) {
setIsConnected(true);
}
} catch (err) {
setIsConnected(false);
}
})();
}, [probeUrl, retryCode]);
return { isConnected, retryConnection };
};

export default CompilationServerConnectionControl;
4 changes: 4 additions & 0 deletions gui/src/app/Compilation/Control/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const publicCompilationServerUrl =
"https://stan-wasm.flatironinstitute.org";
export const localCompilationServerUrl = "http://localhost:8083";
export type ServerType = "public" | "local" | "custom";
33 changes: 16 additions & 17 deletions gui/src/app/FileEditor/StanFileEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import TextEditor from "@SpComponents/TextEditor";
import { ToolbarItem } from "@SpComponents/ToolBar";
import { stancErrorsToCodeMarkers } from "@SpStanc/Linting";
import useStanc from "@SpStanc/useStanc";
import { CompileContext } from "@SpCompileContext/CompileContext";
import { CompileContext } from "@SpCompilation/CompileContext";
import { FunctionComponent, useContext, useMemo, useState } from "react";

type Props = {
Expand All @@ -32,7 +32,7 @@ const StanFileEditor: FunctionComponent<Props> = ({
setEditedFileContent,
);

const { compileStatus, compileMessage, compile, validSyntax } =
const { compileStatus, compileMessage, compile, validSyntax, isConnected } =
useContext(CompileContext);

const hasWarnings = useMemo(() => {
Expand Down Expand Up @@ -89,17 +89,15 @@ const StanFileEditor: FunctionComponent<Props> = ({
});
}
if (editedFileContent && editedFileContent === fileContent) {
if (compileStatus !== "compiling") {
if (validSyntax) {
ret.push({
type: "button",
tooltip: "Compile Stan model",
label: "Compile",
icon: <Settings />,
onClick: compile,
color: "info.dark",
});
}
if (compileStatus !== "compiling" && validSyntax && isConnected) {
ret.push({
type: "button",
tooltip: "Compile Stan model",
label: "Compile",
icon: <Settings />,
onClick: compile,
color: "info.dark",
});
}
if (compileStatus !== "") {
ret.push({
Expand All @@ -118,15 +116,16 @@ const StanFileEditor: FunctionComponent<Props> = ({

return ret;
}, [
validSyntax,
editedFileContent,
hasWarnings,
readOnly,
fileContent,
compile,
requestFormat,
validSyntax,
compileStatus,
isConnected,
compile,
compileMessage,
readOnly,
hasWarnings,
]);

const isCompiling = compileStatus === "compiling";
Expand Down
50 changes: 25 additions & 25 deletions gui/src/app/RunPanel/RunPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FunctionComponent, useCallback, useContext } from "react";
import { FunctionComponent, useCallback, useContext, useMemo } from "react";

import Button from "@mui/material/Button";
import { CompileContext } from "@SpCompileContext/CompileContext";
import { CompileContext } from "@SpCompilation/CompileContext";
import { ProjectContext } from "@SpCore/ProjectContextProvider";
import {
ProjectDataModel,
SamplingOpts,
modelHasUnsavedChanges,
} from "@SpCore/ProjectDataModel";
import { SamplingOpts, modelHasUnsavedChanges } from "@SpCore/ProjectDataModel";
import StanSampler from "@SpStanSampler/StanSampler";
import { StanRun } from "@SpStanSampler/useStanSampler";
import CompiledRunPanel from "./CompiledRunPanel";
import CircularProgress from "@mui/material/CircularProgress";
import Tooltip from "@mui/material/Tooltip";

type RunPanelProps = {
sampler?: StanSampler;
Expand Down Expand Up @@ -41,23 +38,36 @@ const RunPanel: FunctionComponent<RunPanelProps> = ({
sampler.cancel();
}, [sampler]);

const { compile, compileStatus, validSyntax } = useContext(CompileContext);
const { compile, compileStatus, validSyntax, isConnected } =
useContext(CompileContext);

const { data: projectData } = useContext(ProjectContext);

const tooltip = useMemo(() => {
if (!validSyntax) return "Syntax error";
if (!isConnected) return "Not connected to compilation server";
if (!projectData.stanFileContent.trim()) return "No model to compile";
if (modelHasUnsavedChanges(projectData)) return "Model has unsaved changes";
return "";
}, [isConnected, projectData, validSyntax]);

if (!dataIsSaved) {
return <div className="RunPanelPadded">Data not saved</div>;
}

const compileDiv = (
<div>
<Button
variant="contained"
onClick={compile}
disabled={isCompileModelDisabled(projectData, validSyntax)}
>
compile model
</Button>
<Tooltip title={tooltip}>
<span>
<Button
variant="contained"
onClick={compile}
disabled={tooltip != ""}
>
compile model
</Button>
</span>
</Tooltip>
</div>
);

Expand Down Expand Up @@ -89,14 +99,4 @@ const RunPanel: FunctionComponent<RunPanelProps> = ({
);
};

const isCompileModelDisabled = (
projectData: ProjectDataModel,
validSyntax: boolean,
) => {
if (!validSyntax) return true;
if (!projectData.stanFileContent.trim()) return true;
if (modelHasUnsavedChanges(projectData)) return true;
return false;
};

export default RunPanel;
2 changes: 1 addition & 1 deletion gui/src/app/Stanc/useStanc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from "react";
// https://vitejs.dev/guide/assets#importing-script-as-a-worker
// https://vitejs.dev/guide/assets#importing-asset-as-url
import stancWorkerURL from "@SpStanc/stancWorker?worker&url";
import { CompileContext } from "@SpCompileContext/CompileContext";
import { CompileContext } from "@SpCompilation/CompileContext";

const useStanc = (
modelName: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import AnalysisPyWindow from "@SpScripting/Analysis/AnalysisPyWindow";
import useStanSampler, { StanRun } from "@SpStanSampler/useStanSampler";
import AnalysisRWindow from "@SpScripting/Analysis/AnalysisRWindow";
import { CompileContext } from "@SpCompileContext/CompileContext";
import { CompileContext } from "@SpCompilation/CompileContext";

type SamplingWindowProps = {
// none
Expand Down
2 changes: 1 addition & 1 deletion gui/src/app/pages/HomePage/TopBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import CompilationServerConnectionControl from "@SpStanc/CompilationServerConnectionControl";
import CompilationServerConnectionControl from "@SpCompilation/CompilationServerToolbar";
import { Brightness7, DarkMode, Menu, QuestionMark } from "@mui/icons-material";
import AppBar from "@mui/material/AppBar";
import IconButton from "@mui/material/IconButton";
Expand Down
Loading

0 comments on commit b0f9fd2

Please sign in to comment.