Symptom
Launching a project in telnet mode (enableDebugProtocol: false) against a large project staging directory hangs in prepareMainProject for ~80 seconds with no visible progress. The launch eventually proceeds but is unusable in practice. Debug-protocol mode only hits this when stopOnEntry: true, so it's gone unnoticed.
Root cause
fileUtils.findEntryPoint (src/FileUtils.ts:261) runs six sequential findInFiles.find calls, each doing a full recursive walk of every .brs file in the staging dir:
let results = {
...await findInFiles.find({ term: 'sub\\s+RunScreenSaver\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/),
...await findInFiles.find({ term: 'function\\s+RunScreenSaver\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/),
...await findInFiles.find({ term: 'sub\\s+RunUserInterface\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/),
...await findInFiles.find({ term: 'function\\s+RunUserInterface\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/),
...await findInFiles.find({ term: 'sub\\s+main\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/),
...await findInFiles.find({ term: 'function\\s+main\\s*\\(', flags: 'ig' }, projectPath, /.*\.brs/)
};
Each call is serial. The early calls keep running even after a match has been found, and the searches all walk the same tree six times.
Measured timing
On a large staging directory, with main at source/main.brs:1:
22:01:45.641 findEntryPoint() in /Users/.../out/.roku-deploy-staging
22:03:09.835 findEntryPoint() resolved (entryPath: source/main.brs, lineNumber: 1)
~84 seconds for a function that resolves at the first file checked.
Fix options
- Parallel + early-exit –
Promise.all the six calls; short-circuit when any returns a match. ~6x speedup worst case, near-instant when main is at the root.
- Single combined regex – one
findInFiles.find with (?:sub|function)\s+(?:RunScreenSaver|RunUserInterface|main)\s*\(. One tree walk.
- Use brighterscript – there's already a
BscProjectThreaded activated against the staging dir; ask it for the entry function symbol instead of grepping files. Probably overkill.
(2) is the smallest, most direct fix. (1) is the safest mechanical change.
Repro
- Telnet launch (
enableDebugProtocol: false)
- Project with
deepLinkUrl set (so registerEntryBreakpoint actually runs in telnet mode), OR stopOnEntry: true
- Staging directory with many
.brs files
Symptom
Launching a project in telnet mode (
enableDebugProtocol: false) against a large project staging directory hangs inprepareMainProjectfor ~80 seconds with no visible progress. The launch eventually proceeds but is unusable in practice. Debug-protocol mode only hits this whenstopOnEntry: true, so it's gone unnoticed.Root cause
fileUtils.findEntryPoint(src/FileUtils.ts:261) runs six sequentialfindInFiles.findcalls, each doing a full recursive walk of every.brsfile in the staging dir:Each call is serial. The early calls keep running even after a match has been found, and the searches all walk the same tree six times.
Measured timing
On a large staging directory, with
mainatsource/main.brs:1:~84 seconds for a function that resolves at the first file checked.
Fix options
Promise.allthe six calls; short-circuit when any returns a match. ~6x speedup worst case, near-instant whenmainis at the root.findInFiles.findwith(?:sub|function)\s+(?:RunScreenSaver|RunUserInterface|main)\s*\(. One tree walk.BscProjectThreadedactivated against the staging dir; ask it for the entry function symbol instead of grepping files. Probably overkill.(2) is the smallest, most direct fix. (1) is the safest mechanical change.
Repro
enableDebugProtocol: false)deepLinkUrlset (soregisterEntryBreakpointactually runs in telnet mode), ORstopOnEntry: true.brsfiles