chore(protocol): make timeout a protocol-level field#41712
Conversation
Follows #41141, which made signal a protocol-level field. This does the same for timeout: every message carries it on Metadata, computed once on the client and read from progress.timeout on the server, instead of each method declaring its own timeout: float. 0 is the sentinel for no deadline.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…ut-field # Conflicts: # packages/playwright-core/src/client/channels.d.ts # packages/playwright-core/src/server/channels.d.ts # packages/protocol/src/validator.ts
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| addScheme(`${derived}${titleCase(methodName)}ErrorDetails`, `tType('${errorDetailsName}')`); | ||
| } | ||
| channels_ts.push(` ${methodName}(params: ${paramsName}, ${isDispatcher ? `progress: Progress` : `signal: AbortSignal | undefined`}): Promise<${resultName}>;`); | ||
| channels_ts.push(` ${methodName}(params: ${paramsName}, ${isDispatcher ? `progress: Progress` : `options?: CommandOptions`}): Promise<${resultName}>;`); |
There was a problem hiding this comment.
Why are options now optional? Let's make them mandatory (like we had with the signal), so every caller thinks about it?
|
|
||
| async uncheck(options: channels.ElementHandleUncheckOptions & TimeoutOptions = {}) { | ||
| return await this._elementChannel.uncheck({ ...options, timeout: this._frame._timeout(options) }, options.signal); | ||
| return await this._elementChannel.uncheck({ ...options }, { signal: options.signal, timeout: this._frame._timeout(options) }); |
There was a problem hiding this comment.
Let's make all the helper methods like this._frame._timeout(options) handle both timeout and signal - this way the code will be much easier everywhere.
| export type { Binary, Channel, ${structNames.join(', ')} } from '@protocol/structs'; | ||
| `]; | ||
| ` + (target === 'Dispatcher' ? '' : ` | ||
| export type CommandOptions = { signal?: AbortSignal, timeout?: number }; |
There was a problem hiding this comment.
Make both properties required: { signal: AbortSignal | undefined, timeout: number } to ensure all callers doing the right thing?
Make signal and timeout required fields on the generated CommandOptions struct, and pass them explicitly at every channel call site. Internal calls that opt out of a deadline use timeout: 0 as the disabled sentinel.
Test results for "MCP"2 failed 7758 passed, 1249 skipped Merge workflow run. |
Test results for "tests 1"3 flaky49521 passed, 1161 skipped Merge workflow run. |
Follows #41141, which made
signala protocol-level field. This does the same fortimeout: every message carries it onMetadata, computed once on the client and read fromprogress.timeouton the server, instead of each method declaring its owntimeout: float.0is the sentinel for "no deadline", matching whatProgressController.runalready does. It's required onsendMessageToServerso the0is spelled out where it's genuinely meant, rather than hidden behind a?? 0.Most of the diff is mechanical - spec deletions plus regenerated channels/validator, staged separately for review.