Skip to content

Optimize debugger polling to avoid unnecessary computations#372

Merged
thiagoralves merged 1 commit into
developmentfrom
devin/1760471243-optimize-debugger-polling
Oct 14, 2025
Merged

Optimize debugger polling to avoid unnecessary computations#372
thiagoralves merged 1 commit into
developmentfrom
devin/1760471243-optimize-debugger-polling

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

Pull request info

References

Link to Devin run: https://app.devin.ai/sessions/60040dc5fcd84bd094c3394df41ae101

Requested by: Thiago Alves (@thiagoralves)

Description of the changes proposed

This PR optimizes the debugger polling routine to eliminate unnecessary computations that were being performed every 200ms during debugging sessions.

Before: The pollVariables function was extracting variable names, building indexes, looking up function block definitions, and filtering outputs on every poll cycle (every 200ms).

After: All expensive computations are now performed once during debugger session initialization in the useEffect hook:

  • Build complete variableInfoMap for all program variables and function block outputs
  • During polling, only filter the pre-built map to determine which variables need querying based on:
    • Current debug=true flags on variables
    • UI visibility requirements (contacts/coils in ladder diagrams)
    • Currently viewed POU's function block instances

Key changes:

  • Added function block output variable lookup to initialization phase (lines 183-250)
  • Simplified pollVariables to use pre-built map with startsWith filtering instead of rebuilding function block lookups (lines 305-319)
  • Merged two duplicate if (currentPou && currentPou.data.body.language === 'ld') blocks into one

Expected impact: Significant reduction in CPU usage during debugging sessions by avoiding repeated POU traversal, function block definition lookups, and variable filtering.

Important items for review

⚠️ CRITICAL: This code has not been tested in an actual debugging session. Please verify:

  1. Function block output variables are correctly queried for ladder diagrams
  2. The startsWith matching correctly identifies function block variables (format: ${fbInstance.name}.${outputVar.name})
  3. No variables are missed compared to previous implementation
  4. Performance improvement is measurable during active debugging

⚠️ Logic change: The function block variable lookup changed from lazy initialization (adding to map during polling if missing) to eager initialization (all entries created upfront). Verify no edge cases where variables might be missed.

DOD checklist

  • The code is complete and according to developers' standards.
  • I have performed a self-review of my code.
  • Meet the acceptance criteria. (Needs user verification - untested)
  • Unit tests are written and green. (No tests added - optimization only)
  • Test coverage: N/A
  • Integration tests are written and green. (Manual testing required)
  • Changes were communicated and updated in the ticket description.
  • Reviewed and accepted by the Product Owner.
  • End-to-end test are successful. (Requires manual debugger session testing)

- Move variable extraction and index building to useEffect initialization instead of running on every poll cycle
- Build complete variableInfoMap once during debugger session start, including all program variables and function block outputs
- Simplify pollVariables function to only check which variables currently need querying based on debug flags and UI visibility
- Remove duplicate function block lookup logic from poll cycle - now only checks which variables to include from pre-built map
- This significantly reduces CPU usage during debugging by avoiding repeated traversal of POUs, function block definitions, and variable lookups every 200ms

Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 14, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

@thiagoralves thiagoralves requested a review from Copilot October 14, 2025 20:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR optimizes the debugger polling routine by moving expensive computations from the 200ms polling loop to initialization time, reducing CPU usage during debugging sessions.

  • Moved function block output variable lookup from polling loop to initialization phase
  • Simplified polling logic to filter pre-built variable map instead of rebuilding lookups
  • Merged duplicate ladder diagram logic blocks

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 305 to 315
functionBlockInstances.forEach((fbInstance) => {
const fbTypeName = fbInstance.type.value.toUpperCase()

let fbVariables:
| Array<{ name: string; class: string; type: { definition: string; value: string } }>
| undefined

const standardFB = StandardFunctionBlocks.pous.find(
(fb: { name: string }) => fb.name.toUpperCase() === fbTypeName,
)
if (standardFB) {
fbVariables = standardFB.variables
} else {
const customFB = currentProject.data.pous.find(
(pou) => pou.type === 'function-block' && pou.data.name.toUpperCase() === fbTypeName,
)
if (customFB && customFB.type === 'function-block') {
fbVariables = customFB.data.variables as Array<{
name: string
class: string
type: { definition: string; value: string }
}>
Array.from(variableInfoMapRef.current!.entries()).forEach(([_, varInfo]) => {
if (
varInfo.pouName === programInstance.name &&
varInfo.variable.name.startsWith(`${fbInstance.name}.`)
) {
const compositeKey = `${varInfo.pouName}:${varInfo.variable.name}`
debugVariableKeys.add(compositeKey)
}
}

if (fbVariables) {
const boolOutputs = fbVariables.filter(
(v) =>
(v.class === 'output' || v.class === 'inOut') &&
v.type.definition === 'base-type' &&
v.type.value.toUpperCase() === 'BOOL',
)

boolOutputs.forEach((outputVar) => {
const debugPath = `RES0__${programInstance.name.toUpperCase()}.${fbInstance.name.toUpperCase()}.${outputVar.name.toUpperCase()}`
const index = debugVariableIndexes.get(debugPath)

if (index !== undefined) {
const blockVarName = `${fbInstance.name}.${outputVar.name}`
const compositeKey = `${programInstance.name}:${blockVarName}`
debugVariableKeys.add(compositeKey)

if (!variableInfoMapRef.current?.has(index)) {
variableInfoMapRef.current?.set(index, {
pouName: programInstance.name,
variable: {
name: blockVarName,
type: { definition: 'base-type', value: 'bool' },
class: 'local',
location: '',
documentation: '',
debug: false,
},
})
}
}
})
}
})
})
Copy link

Copilot AI Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested loop creates O(n×m) complexity where the outer loop iterates over function block instances and the inner loop iterates over all variable entries. Consider building a Map keyed by POU name and function block instance name during initialization to avoid this nested iteration during polling.

Copilot uses AI. Check for mistakes.
@thiagoralves thiagoralves merged commit 580369d into development Oct 14, 2025
8 checks passed
@thiagoralves thiagoralves deleted the devin/1760471243-optimize-debugger-polling branch October 14, 2025 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants