Skip to content

Commit d50af6c

Browse files
authored
Merge pull request #8564 from sagemathinc/latex-no-timeout
Latex Timeout Fix
2 parents 07002cf + f88f498 commit d50af6c

File tree

6 files changed

+77
-13
lines changed

6 files changed

+77
-13
lines changed

src/packages/frontend/cspell.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
"ARIMA",
88
"autograde",
99
"autograding",
10+
"bibtex",
1011
"Bioconductor",
1112
"bioinformatics",
1213
"CoCalc",
1314
"conat",
1415
"dplyr",
1516
"dstream",
17+
"errorstopmode",
1618
"formatjs",
1719
"geospatial",
1820
"ggplot",
@@ -22,15 +24,21 @@
2224
"katex",
2325
"knitr",
2426
"kucalc",
27+
"latexmk",
28+
"lualatex",
29+
"luatex",
2530
"mathjax",
2631
"matplotlib",
2732
"Miniterm",
2833
"nbconvert",
2934
"nbgrader",
3035
"nbviewer",
36+
"nonstopmode",
3137
"Ollama",
3238
"onprem",
39+
"pdflatex",
3340
"plotly",
41+
"pythontex",
3442
"rclass",
3543
"rereturn",
3644
"respawns",
@@ -53,7 +61,10 @@
5361
"synctex",
5462
"tidymodels",
5563
"tidyverse",
64+
"tikz",
5665
"timetravel",
66+
"xelatex",
67+
"xetex",
5768
"tolerations",
5869
"undelete",
5970
"undeleting"

src/packages/frontend/frame-editors/code-editor/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ import {
6464
syntax2tool,
6565
} from "@cocalc/util/code-formatter";
6666
import {
67-
IS_TIMEOUT_CALLING_PROJECT,
67+
isTimeoutCallingProject,
6868
TIMEOUT_CALLING_PROJECT_MSG,
6969
} from "@cocalc/util/consts/project";
7070
import {
@@ -1921,7 +1921,7 @@ export class Actions<
19211921
if (error === undefined) {
19221922
return "";
19231923
}
1924-
if (IS_TIMEOUT_CALLING_PROJECT(error)) {
1924+
if (isTimeoutCallingProject(error)) {
19251925
return TIMEOUT_CALLING_PROJECT_MSG;
19261926
}
19271927
if (typeof error == "string") {

src/packages/frontend/frame-editors/latex-editor/build.tsx

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Show the last latex build log, i.e., output from last time we ran the LaTeX buil
99

1010
import Ansi from "@cocalc/frontend/components/ansi-to-react";
1111
import { Button, Flex, Tooltip } from "antd";
12-
import { Fragment, useState } from "react";
12+
import { Fragment, useEffect, useMemo, useRef, useState } from "react";
1313

1414
import { AntdTabItem, Tab, Tabs } from "@cocalc/frontend/antd-bootstrap";
1515
import { CSS, React, Rendered, useRedux } from "@cocalc/frontend/app-framework";
@@ -52,6 +52,25 @@ export const Build: React.FC<Props> = React.memo((props) => {
5252
BUILD_SPECS.latex.label,
5353
);
5454
const [error_tab, set_error_tab] = useState<string | null>(null);
55+
const logContainerRef = useRef<HTMLDivElement>(null);
56+
const [shownLog, setShownLog] = useState<string>("");
57+
58+
// Compute whether we have running jobs - this determines UI precedence
59+
const hasRunningJobs = useMemo(() => {
60+
return (
61+
build_logs?.some((job) => {
62+
const jobJS: BuildLog = job?.toJS();
63+
return jobJS?.type === "async" && jobJS?.status === "running";
64+
}) ?? false
65+
);
66+
}, [build_logs]);
67+
68+
// Auto-scroll to bottom when log updates
69+
useEffect(() => {
70+
if (logContainerRef.current) {
71+
logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;
72+
}
73+
}, [shownLog]);
5574

5675
let no_errors = true;
5776

@@ -179,7 +198,8 @@ export const Build: React.FC<Props> = React.memo((props) => {
179198
}
180199

181200
function render_logs(): Rendered {
182-
if (status) return;
201+
// Hide logs when jobs are running - show live output instead
202+
if (hasRunningJobs) return;
183203

184204
const items: AntdTabItem[] = [];
185205

@@ -230,12 +250,17 @@ export const Build: React.FC<Props> = React.memo((props) => {
230250
const infos: React.JSX.Element[] = [];
231251
let isLongRunning = false;
232252
let logTail = "";
253+
233254
build_logs.forEach((infoI, key) => {
234255
const info: ExecuteCodeOutput = infoI?.toJS();
235256
if (!info || info.type !== "async" || info.status !== "running") return;
236257
const stats_str = getResourceUsage(info.stats, "last");
237258
const start = info.start;
238-
logTail = tail((info.stdout ?? "") + (info.stderr ?? ""), 6);
259+
logTail = tail((info.stdout ?? "") + (info.stderr ?? ""), 100);
260+
// Update state for auto-scrolling effect
261+
if (logTail !== shownLog) {
262+
setShownLog(logTail);
263+
}
239264
isLongRunning ||=
240265
typeof start === "number" &&
241266
webapp_client.server_time() - start > WARN_LONG_RUNNING_S * 1000;
@@ -287,19 +312,36 @@ export const Build: React.FC<Props> = React.memo((props) => {
287312
</Tooltip>
288313
</Flex>
289314
</div>
290-
<div style={logStyle}>
315+
<div
316+
style={{
317+
...logStyle,
318+
maxHeight: "300px",
319+
overflow: "hidden",
320+
display: "flex",
321+
flexDirection: "column",
322+
}}
323+
>
291324
<div
292325
style={{
293326
fontWeight: "bold",
294327
whiteSpace: "nowrap",
295328
overflow: "hidden",
296329
textOverflow: "ellipsis",
330+
flexShrink: 0,
297331
}}
298332
>
299333
{status}
300334
{"\n"}
301335
</div>
302-
{logTail}
336+
<div
337+
ref={logContainerRef}
338+
style={{
339+
overflowY: "auto",
340+
flexGrow: 1,
341+
}}
342+
>
343+
<Ansi>{shownLog}</Ansi>
344+
</div>
303345
</div>
304346
</>
305347
);

src/packages/frontend/frame-editors/latex-editor/latexmk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export function build_command(
168168
/*
169169
-f: force even when there are errors
170170
-g: ignore heuristics to stop processing latex (sagetex)
171-
silent: **don't** set -silent, also silences sagetex mesgs!
171+
silent: **don't** set -silent, also silences sagetex messages!
172172
bibtex: a default, run bibtex when necessary
173173
synctex: forward/inverse search in pdf
174174
nonstopmode: continue after errors (otherwise, partial files)

src/packages/frontend/frame-editors/latex-editor/util.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
ExecOpts,
1111
ExecOutput,
1212
} from "@cocalc/frontend/frame-editors/generic/client";
13-
import { IS_TIMEOUT_CALLING_PROJECT } from "@cocalc/util/consts/project";
13+
import { isTimeoutCallingProject } from "@cocalc/util/consts/project";
1414
import { ExecOptsBlocking } from "@cocalc/util/db-schema/projects";
1515
import { separate_file_extension } from "@cocalc/util/misc";
1616
import { ExecuteCodeOutputAsync } from "@cocalc/util/types/execute-code";
@@ -99,7 +99,7 @@ async function gatherJobInfo(
9999
return;
100100
}
101101
await delay(1000 * wait_s);
102-
wait_s = Math.min(5, wait_s + 1);
102+
wait_s = Math.min(3, wait_s + 0.5);
103103
}
104104
} catch {
105105
return;
@@ -177,7 +177,7 @@ export async function runJob(opts: RunJobOpts): Promise<ExecOutput> {
177177
set_job_info(output);
178178
return output;
179179
} catch (err) {
180-
if (IS_TIMEOUT_CALLING_PROJECT(err)) {
180+
if (isTimeoutCallingProject(err)) {
181181
// This will eventually be fine, hopefully. We continue trying to get a reply.
182182
await delay(100);
183183
} else {

src/packages/util/consts/project.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,20 @@ export const TIMEOUT_CALLING_PROJECT = "timeout";
1010
export const TIMEOUT_CALLING_PROJECT_MSG =
1111
"Timeout communicating with project.";
1212

13-
export const IS_TIMEOUT_CALLING_PROJECT = (err) => {
13+
/**
14+
* Checks if an error represents a timeout when communicating with a project.
15+
*
16+
* Handles both legacy and conat-based timeout errors:
17+
* - Legacy: String "timeout"
18+
* - Conat: ConatError with code 408 (HTTP Request Timeout)
19+
* See @cocalc/conat/core/client.ts lines 1391, 1937-1939 where 408 timeouts are thrown
20+
*/
21+
export function isTimeoutCallingProject(err): boolean {
1422
if (err === TIMEOUT_CALLING_PROJECT) {
1523
return true;
1624
}
25+
if (err?.constructor?.name === "ConatError" && err?.code === 408) {
26+
return true;
27+
}
1728
return false;
18-
};
29+
}

0 commit comments

Comments
 (0)