Skip to content

Conversation

@nvborisenko
Copy link
Member

@nvborisenko nvborisenko commented Nov 29, 2025

User description

Performance optimization.

💥 What does this PR do?

🔧 Implementation Notes

Task for listening to incoming messages as LongRunning, meaning CLR will allocate new thread as fast as possible.

🔄 Types of changes

  • Cleanup (formatting, renaming)

PR Type

Enhancement


Description

  • Add TaskCreationOptions.LongRunning to BiDi message receiver

  • Enables CLR to allocate thread immediately for incoming messages

  • Improves performance of remote message listening


Diagram Walkthrough

flowchart LR
  A["StartNew without LongRunning"] -->|"Add TaskCreationOptions.LongRunning"| B["StartNew with LongRunning"]
  B -->|"Result"| C["Immediate thread allocation for message receiving"]
Loading

File Walkthrough

Relevant files
Enhancement
Broker.cs
Add LongRunning option to message receiver task                   

dotnet/src/webdriver/BiDi/Broker.cs

  • Added TaskCreationOptions.LongRunning parameter to
    _myTaskFactory.StartNew() call
  • Signals CLR to allocate a new thread immediately for the message
    receiving task
  • Improves performance by avoiding thread pool delays for long-running
    operations
+1/-1     

@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing auditing: The new long-running task start for receiving messages does not include any
auditing/logging of critical actions, making it unclear whether message processing will be
captured for audit trails.

Referred Code
_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token), TaskCreationOptions.LongRunning).Unwrap();
_eventEmitterTask = _myTaskFactory.StartNew(ProcessEventsAwaiterAsync).Unwrap();

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Error handling gap: Starting the long-running receive task lacks explicit error handling or cancellation fault
propagation, risking unobserved task exceptions or silent failures.

Referred Code
    _receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token), TaskCreationOptions.LongRunning).Unwrap();
    _eventEmitterTask = _myTaskFactory.StartNew(ProcessEventsAwaiterAsync).Unwrap();
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Input validation context: The change alters threading behavior for receiving remote messages without showing
validation or sanitization of incoming data, which may be handled elsewhere but is not
evident here.

Referred Code
_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token), TaskCreationOptions.LongRunning).Unwrap();
_eventEmitterTask = _myTaskFactory.StartNew(ProcessEventsAwaiterAsync).Unwrap();

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Remove inappropriate long-running task option

Remove TaskCreationOptions.LongRunning because the ReceiveMessagesAsync method
is I/O-bound, and this option is intended for CPU-bound tasks.

dotnet/src/webdriver/BiDi/Broker.cs [64]

-_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token), TaskCreationOptions.LongRunning).Unwrap();
+_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token)).Unwrap();
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly points out that TaskCreationOptions.LongRunning is generally for CPU-bound tasks, and using it for an I/O-bound task like ReceiveMessagesAsync can be inefficient and lead to thread over-subscription, which contradicts the PR's goal of improving performance.

High
  • More

@nvborisenko
Copy link
Member Author

@RenderMichael AI is correct here?

Remove TaskCreationOptions.LongRunning because the ReceiveMessagesAsync method
is I/O-bound, and this option is intended for CPU-bound tasks.

@RenderMichael
Copy link
Contributor

@nvborisenko I think the AI is hallucinating as usual, and has it backwards. This StackOverflow answer says it makes an extra thread because the process is expected to use less of the CPU (if I am reading it right).

My understanding is, a LongRunning task will be picked up ASAP when it is done, which seems like a very good thing.

@RenderMichael
Copy link
Contributor

Reading more about LongRunning, I’m seeing guidance that we should just create a Thread and control it directly because that task option just does the same.

I’m beginning to warm up to System.Threading.Channels, honestly. I know it’s another dependency, but it’s by Microsoft and solves our issue very elegantly.

@nvborisenko
Copy link
Member Author

System.Threading.Channels will not help, in any case we need run producer/consumer in backgroung thread.

@nvborisenko nvborisenko merged commit 67fae55 into SeleniumHQ:trunk Nov 30, 2025
13 checks passed
@nvborisenko nvborisenko deleted the bidi-listener-long-running-task branch November 30, 2025 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants