首页 / 资讯中心 / 文章详情

Language Server Protocol 3.19 工作进度取消机制:window/workDoneProgress/cancel 通知深度解析

Language Server Protocol 3.19 工作进度取消机制:window/workDoneProgress/cancel 通知深度解析 ★ FEATURED ARTICLE
开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载window/workDoneProgress/cancel是 LSPLanguage Server Protocol中由客户端主动发起、用于**取消服务器端已创建的工作进度work done progress**的标准通知。本文以 LSP 3.19 规范文档为骨架结合本仓库中的规范正文、类型定义与机器可读元数据metaModel完整讲解该通知的协议格式、触发场景、与cancellable标记的关系以及它和window/workDoneProgress/create、$/progress、$/cancelRequest等相邻机制的配合方式帮助语言服务器实现者与客户端开发者正确落地长任务可取消的进度交互。一、协议定位谁在什么时候发送这条通知1.1 消息方向与语义依据 3.19 规范文档window/workDoneProgress/cancel是一条从客户端发送到服务器client → server的通知notification用于取消一个由服务器端通过window/workDoneProgress/create请求发起的进度。其核心语义可以拆解为三点取消对象是服务器发起的进度只有先由服务器调用window/workDoneProgress/create向客户端申请创建进度客户端后续才有权用本条通知将其取消。取消无需cancellable: true该进度不必被标记为可取消客户端仍可以发送取消通知。取消原因由客户端自行决定规范明确列举了若干场景——例如发生错误in case of error、**重新加载工作区reloading a workspace**等客户端可以因任何理由发起取消。这一点可以在机器可读的元数据模型中得到印证。metaModel.json 中该通知被登记为{ method: window/workDoneProgress/cancel, typeName: WorkDoneProgressCancelNotification, messageDirection: clientToServer, params: { kind: reference, name: WorkDoneProgressCancelParams }, documentation: The window/workDoneProgress/cancel notification is sent from the client to the server to cancel a progress\ninitiated on the server side. }可见其messageDirection被明确标记为clientToServer与客户端主动发起的定位一致。1.2 与请求取消$/cancelRequest的本质区别容易混淆的是$/cancelRequest。两者名称相近但语义完全不同维度window/workDoneProgress/cancel$/cancelRequest发送方客户端 → 服务器客户端 → 服务器取消对象服务器发起的进度条work done progress一个尚未返回响应的请求request载荷WorkDoneProgressCancelParams.tokenCancelParams.id请求 ID取消后是否必须回应进度只是 UI 层反馈规范不要求对进度做响应被取消的请求仍必须返回响应不能悬空典型场景错误、重载工作区时撤销进度条用户中断textDocument/references等耗时请求关于$/cancelRequest的细节可参见 specification.md被取消的请求依然需要回包若以错误响应结束规范建议使用错误码ErrorCodes.RequestCancelled数值为-32800见 specification.md。二、协议格式与参数类型2.1 通知定义按 3.19 规范通知格式为Notificationmethod:window/workDoneProgress/cancelparams:WorkDoneProgressCancelParams2.2 参数类型 WorkDoneProgressCancelParamsexport interface WorkDoneProgressCancelParams { /** * The token to be used to report progress. */ token: ProgressToken; }其中ProgressToken的定义见 specification.mdtype ProgressToken integer | string;即整数或字符串均可作为进度 token。token字段正是window/workDoneProgress/create请求在WorkDoneProgressCreateParams中携带的那个 token见 workDoneProgressCreate.md客户端通过$/progress通知跟踪该 token 对应的进度需要取消时再用同一个 token 发起本条通知。在 metaModel.json 中WorkDoneProgressCancelParams的结构化定义为{ name: WorkDoneProgressCancelParams, properties: [ { name: token, type: { kind: reference, name: ProgressToken }, documentation: The token to be used to report progress. } ] }从 JSON Schema 派生实现如 vscode-languageserver 的WorkDoneProgressCancelNotification类型时可直接以该结构化定义为准。三、取消机制在整体进度模型中的位置要正确理解取消必须先把 LSP 的进度模型串起来。进度机制自3.15.0起加入协议见 workDoneProgress.md完整链路如下3.1 三种进度载荷$/progress 的 value工作进度通过通用的$/progress通知上报value有三种形态详见 workDoneProgress.mdWorkDoneProgressBeginkind: begin启动进度包含必填的title以及可选的cancellable、message、percentage取值范围 [0, 100]不提供时表示无限进度。WorkDoneProgressReportkind: report进度更新可携带cancellable、message、percentage。WorkDoneProgressEndkind: end结束进度可携带可选的最终message。cancellable字段的准确语义是是否在界面上显示取消按钮而非是否允许被取消。这一点正是取消通知能绕过它的前提——见第三节分析。3.2 两种发起方式进度有两种发起路径见 workDoneProgress.md 的 Initiating Work Done Progress 一节客户端发起的进度client initiated客户端在请求参数中附带workDoneToken属性如textDocument/reference请求中的workDoneToken。token 仅在请求未返回响应期间有效取消这类进度的方式是直接取消对应请求$/cancelRequest而不是window/workDoneProgress/cancel。服务器发起的进度server initiated服务器调用window/workDoneProgress/create请求向客户端申请 token随后用$/progress上报。window/workDoneProgress/cancel正是用于取消这一类进度。一个典型的服务器发起进度的 JSON-RPC 调用链为[server] window/workDoneProgress/create { token: 1d546990-... } [server] $/progress { token: ..., value: { kind: begin, title: Re-indexing, ... } } [server] $/progress { token: ..., value: { kind: report, percentage: 40, ... } } [client] window/workDoneProgress/cancel { token: 1d546990-... } ← 本文主题 [server] $/progress { token: ..., value: { kind: end, ... } }3.3 为什么客户端可以取消不可取消的进度规范原文 明确指出The progress need not be marked ascancellableto be cancelled and a client may cancel a progress for any number of reasons: in case of error, reloading a workspace etc.原因在于协议设计上把用户界面上是否提供取消按钮cancellable与客户端是否有权撤销进度cancel 通知解耦cancellable: true时客户端会在进度 UI 上显示取消按钮用户点击后客户端发送window/workDoneProgress/cancel这是一种用户主动取消即使cancellable: false甚至未设置客户端依然可能在自身状态异常如请求出错、需要重载工作区时主动撤销进度避免界面残留过期进度条。因此服务器实现者不能把cancellable: false当作绝不会收到取消通知的保证仍需对任意时刻到来的取消通知做好幂等处理例如标记进度为已取消丢弃后续 report。四、协议使用前提与能力协商4.1 客户端能力window.workDoneProgress服务器只有在客户端声明支持window.workDoneProgress能力时才允许使用window/workDoneProgress/create发起进度这保证了向后兼容性见 workDoneProgress.md 的 Server Initiated Progress 一节。对应客户端能力定义为window?: { /** * Whether client supports server initiated progress using the * window/workDoneProgress/create request. */ workDoneProgress?: boolean; };换言之取消通知的有效性以该能力协商为前提没有声明window.workDoneProgress的客户端不应发送window/workDoneProgress/cancel声明了的客户端则在创建进度后可以随时取消。4.2 服务器能力WorkDoneProgressOptions反向地对于客户端在请求参数中携带workDoneToken的客户端发起进度服务器需要在其提供者能力如referencesProvider中声明workDoneProgress: true客户端才值得在发送请求前建立进度 UI。对应类型export interface WorkDoneProgressOptions { workDoneProgress?: boolean; }4.3 initialize 阶段的特例在握手阶段存在一个例外客户端可在initialize请求参数中设置workDoneToken此时服务器且仅能用该 token可以通过$/progress上报初始化进度参见 initialize.md。该 token 的取消同样不属于window/workDoneProgress/cancel的职责范围。五、服务器端实现要点与校验清单结合 workDoneProgressCreate.md 与 workDoneProgressCancel.md服务器实现取消处理时建议遵守以下要点token 一一对应取消通知携带的token必须是此前window/workDoneProgress/create发放过的 token。规范要求 create 请求中提供的 token只能使用一次一个 begin、若干 report、一个 end取消处理同样应基于该 token 定位唯一的进度实例。取消后仍发送 end收到取消通知后服务器应停止继续发送 report并以WorkDoneProgressEnd可携带最终message说明结果如 cancelled收尾保证进度状态机完整闭合。容忍未知 token对无法识别的 token 保持静默忽略即可协议未定义取消通知的响应或错误返回它是 notification 而非 request。与 create 的错误处理区分window/workDoneProgress/create作为 request出错时会返回错误码与消息且规范规定——若 create 请求出错服务器不得使用该 token 发送任何进度通知见 workDoneProgressCreate.md。取消通知则没有此类约束。六、3.17 与 3.19 的版本一致性对比本仓库中 3.17 与 3.19 两个版本3.17 版本文档 与 3.19 版本文档 在方法名、消息方向、参数类型上完全一致均定义token: ProgressToken。也就是说window/workDoneProgress/cancel自引入以来协议面保持稳定实现方只需按一套语义处理即可无需按版本分支。七、总结window/workDoneProgress/cancel是 LSP 进度体系中唯一一条由客户端主动撤销服务器发起进度的通知消息方向为 client → server方法名为window/workDoneProgress/cancel载荷为WorkDoneProgressCancelParams仅含一个token: ProgressToken字段integer | string取消不要求进度标记cancellable客户端可因错误、重载工作区等原因随时取消它只适用于服务器发起进度经window/workDoneProgress/create创建与取消请求的$/cancelRequest分工明确能力协商方面服务器使用 create 需客户端声明window.workDoneProgress能力而取消通知本身无需额外能力。对语言服务器实现者而言正确做法是把window/workDoneProgress/cancel视为对进度实例的外部撤销信号收到后停止 report、发送end收尾并保证幂等对客户端实现者而言则是在需要撤销 UI 进度时用创建时的 token 原样回传即可。赞分享开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载相关推荐Language Server Protocol 中的窗口工作进度取消机制window/workDoneProgress/cancel 详解Language Server Protocol 中的窗口工作进度取消机制window/workDoneProgress/cancel 详解 在 Langua开发工具LSP 3.17 服务器发起的工作进度机制window/workDoneProgress/create 请求深度解析LSP 3.17 服务器发起的工作进度机制window/workDoneProgress/create 请求深度解析 导读 window/workDonePr开发工具language-server-protocol 深度解析textDocument/didOpen 文档打开通知与文本同步机制language server protocol 深度解析textDocument/didOpen 文档打开通知与文本同步机制 textDocument/di开发工具上一篇TVBoxOSC一个 APK 把旧电视盒变成直播点播播放器下一篇Scrapegraph-ai 环境搭建与上手用四个问题跑通你的第一次 AI 爬虫创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站