SeleniumHQ / SeleniumHQ/selenium
[🚀 Feature]: [BiDi] High latency in Python & Ruby BiDi/CDP command execution due to sleep-based polling
- Dominant language
- Java
- Stars
- 34.5k
- Forks
- 8.7k
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 92
Description
### Description
### Body
### Describe the bug
When executing WebDriver BiDi or CDP commands via WebSockets in Python and Ruby bindings, there is a substantial mandatory latency (~50-100ms) per command execution.
This latency occurs because the websocket connection wrappers in both Python and Ruby execute a polling loop to wait for the target message ID to appear in the received messages queue, using a `sleep(0.1)` (100ms) sleep interval.
Even if the browser responds immediately in less than 1ms, the calling thread is forced to sleep until the next poll cycle, creating a severe performance bottleneck for high-frequency command execution (e.g., listening/responding to console log events, network traffic monitoring, etc.).
### Steps to reproduce
Run any WebDriver BiDi command (e.g., executing scripts or navigating contexts) repeatedly, and measure the round-trip latency. It consistently floors around ~50-100ms per command.
### Expected behavior
The command execution thread should block and wake up immediately when the browser's response is received on the WebSocket listener thread, without sleeping or busy-polling.
### Proposed Solution
Replace the sleep-based polling loops with standard thread synchronization primitives:
1. **Python**: Map each pending command ID to a `threading.Event` and block using `event.wait(timeout)`. Signal/set the event immediately when the response is processed.
2. **Ruby**: Map each pending command ID to a `Thread::ConditionVariable` and block using `cond.wait(mutex, timeout)`. Signal the condition variable immediately when the response is processed.
### Have you considered any alternatives or workarounds?
_No response_
Contributor guide
Research direction
Start in the Python and Ruby WebSocket connection wrappers, tracing the sleep-based polling loops that wait for pending command IDs and the listener path that processes responses. Reproduce repeated WebDriver BiDi or CDP commands and measure the round-trip latency; done means the waiting command wakes when its response is processed rather than on a polling interval, while preserving timeout behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, ruby
- Domain
- backend-api-design, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100