Skip to content

Commit

Permalink
feat: add request timeout configuration for ClickHouse connection #46
Browse files Browse the repository at this point in the history
  • Loading branch information
caioricciuti committed Jan 20, 2025
1 parent 0a5bdef commit 2bb3cd4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 6 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ ENV VITE_CLICKHOUSE_USER=""
ENV VITE_CLICKHOUSE_PASS=""
ENV VITE_CLICKHOUSE_USE_ADVANCED=""
ENV VITE_CLICKHOUSE_CUSTOM_PATH=""
ENV VITE_CLICKHOUSE_REQUEST_TIMEOUT=30000

RUN addgroup -S ch-group -g 1001 && adduser -S ch-user -u 1001 -G ch-group

Expand Down
1 change: 1 addition & 0 deletions inject-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const envVars = {
VITE_CLICKHOUSE_PASS: process.env.VITE_CLICKHOUSE_PASS || "",
VITE_CLICKHOUSE_USE_ADVANCED: process.env.VITE_CLICKHOUSE_USE_ADVANCED || "",
VITE_CLICKHOUSE_CUSTOM_PATH: process.env.VITE_CLICKHOUSE_CUSTOM_PATH || "",
VITE_CLICKHOUSE_REQUEST_TIMEOUT: process.env.VITE_CLICKHOUSE_REQUEST_TIMEOUT || 3000,
};

const scriptContent = `
Expand Down
47 changes: 44 additions & 3 deletions src/pages/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
User,
Lock,
Cog,
FileClock,
} from "lucide-react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
Expand Down Expand Up @@ -53,6 +54,11 @@ const formSchema = z.object({
password: z.string().optional(),
useAdvanced: z.boolean().optional(),
customPath: z.string().optional(),
requestTimeout: z.coerce
.number()
.int("Request timeout must be a whole number")
.min(1000, "Request timeout must be at least 1000 millisecond")
.max(600000, "Request timeout must not exceed 600000 milliseconds"),
});

export default function SettingsPage() {
Expand All @@ -78,6 +84,7 @@ export default function SettingsPage() {
url: credential?.url,
username: credential?.username,
password: credential?.password,
requestTimeout: credential?.requestTimeout,
};

const form = useForm<z.infer<typeof formSchema>>({
Expand All @@ -86,6 +93,7 @@ export default function SettingsPage() {
url: credential?.url || "",
username: credential?.username || "",
password: credential?.password || "",
requestTimeout: credential?.requestTimeout || 30000,
useAdvanced: false,
customPath: "",
},
Expand All @@ -97,6 +105,7 @@ export default function SettingsPage() {
values.url === currentFormValues.url &&
values.username === currentFormValues.username &&
values.password === currentFormValues.password &&
values.requestTimeout === currentFormValues.requestTimeout &&
isServerAvailable
) {
toast.info("No changes detected.");
Expand All @@ -114,6 +123,7 @@ export default function SettingsPage() {
password: values.password || "",
useAdvanced: values.useAdvanced || false,
customPath: values.customPath || "",
requestTimeout: values.requestTimeout, // No need to convert, already a number
});
await checkServerStatus();
setCredentialSource("app");
Expand All @@ -132,6 +142,7 @@ export default function SettingsPage() {
password: "",
useAdvanced: false,
customPath: "",
requestTimeout: 30000,
});
toast.success("Disconnected from ClickHouse server.");
navigate("/settings");
Expand Down Expand Up @@ -207,7 +218,7 @@ export default function SettingsPage() {
{...field}
/>
</FormControl>
<FormDescription>
<FormDescription className="text-xs">
The URL of your ClickHouse server, including
protocol and port
</FormDescription>
Expand Down Expand Up @@ -313,7 +324,7 @@ export default function SettingsPage() {
<Cog className="h-4 w-4" />
Advanced Settings
</FormLabel>
<FormDescription>
<FormDescription className="text-xs">
Enable custom path handling for the ClickHouse
URL
</FormDescription>
Expand All @@ -337,7 +348,7 @@ export default function SettingsPage() {
{...field}
/>
</FormControl>
<FormDescription>
<FormDescription className="text-xs">
Specify the custom path if you're using
path-based routing
</FormDescription>
Expand All @@ -346,6 +357,36 @@ export default function SettingsPage() {
)}
/>
)}

<FormField
control={form.control}
name="requestTimeout"
render={({ field }) => (
<FormItem>
<FormLabel className="flex items-center gap-2">
<FileClock className="h-4 w-4" />
Request Timeout (ms)
</FormLabel>
<FormControl>
<Input
className="font-mono"
disabled={isLoadingCredentials}
type="number"
min={1}
max={600000}
placeholder="30000"
{...field}
onChange={(e) => field.onChange(e.target.value)}
/>
</FormControl>
<FormDescription className="text-xs">
Set the request timeout in milliseconds. Must be
between 1000 and 600000. (Default: 30000)
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</div>

{credentialSource !== "env" && (
Expand Down
10 changes: 7 additions & 3 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const useAppStore = create<AppState>()(
password: "",
useAdvanced: false,
customPath: "",
requestTimeout: 30000,
},
clickHouseClient: null,
isLoadingCredentials: false,
Expand All @@ -63,7 +64,7 @@ const useAppStore = create<AppState>()(
clickhouseSettings: {
max_result_rows: "0",
max_result_bytes: "0",
result_overflow_mode: "throw" as OverflowMode,
result_overflow_mode: "break" as OverflowMode,
},
setCredentialSource: (source) => set({ credentialSource: source }),
setCredential: async (credential) => {
Expand All @@ -75,9 +76,10 @@ const useAppStore = create<AppState>()(
pathname: credential.customPath, // Use custom path for proxy
username: credential.username,
password: credential.password || "",
request_timeout: credential.requestTimeout || 30000,
clickhouse_settings: {
...get().clickhouseSettings,
result_overflow_mode: "throw",
result_overflow_mode: "break",
},
});
set({ clickHouseClient: client });
Expand All @@ -102,6 +104,7 @@ const useAppStore = create<AppState>()(
pathname: credentials.customPath, // Ensure custom path is applied
username: credentials.username,
password: credentials.password || "",
request_timeout: credentials.requestTimeout || 30000,
clickhouse_settings: clickhouseSettings,
});

Expand All @@ -120,11 +123,12 @@ const useAppStore = create<AppState>()(
password: "",
useAdvanced: false,
customPath: "",
requestTimeout: 30000,
},
clickhouseSettings: {
max_result_rows: "0",
max_result_bytes: "0",
result_overflow_mode: "throw",
result_overflow_mode: "break" as OverflowMode
},
clickHouseClient: null,
isServerAvailable: false,
Expand Down
1 change: 1 addition & 0 deletions src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface Credential {
url: string;
username: string;
password: string;
requestTimeout: number;
useAdvanced: boolean;
customPath: string;
}
Expand Down

0 comments on commit 2bb3cd4

Please sign in to comment.