RFC-0053:表情符号

RFC-0053:墓碑
状态已接受
领域
  • FIDL
说明

该方案的目标是允许服务器在关闭连接之前发送消息,以指示连接关闭的原因。

作者
提交日期(年-月-日)2018-07-19
审核日期(年-月-日)2018-10-04

“这是你的服务器”

摘要

该方案的目标是允许服务器在发送事件前 关闭指示连接原因的连接 已关闭。虽然 墓碑 ,它们尚未实现。

设计初衷

目前,还没有标准方法让服务器向客户端传达 连接已关闭。这就意味着, 而确保错误处理则由开发者负责。开发者可以 并预见到这一点,并在其消息中内置特殊的错误处理功能,或者简单地 忽略错误处理(并存在不可诊断的错误)。

服务器的一个应用场景是,其中的错误大多是非常严重的错误 系统会关闭与客户端的所有连接在此类情况下,开发者需要 一种通用的错误报告机制,因为对方法的所有有效调用 都会因同样的错误而终止。声明电能的替代方案 都会非常麻烦和麻烦。

此 FTP 的目的不在于提供详尽的错误报告 机制。具体而言,能够传达大量细节 (包括详细消息、进程状态或传播原因) 连接终端不在范围内。

此 FTP 也没有定义一组常见错误代码的目标。

设计

此提案修改了传输格式、源语言和第一类 语言绑定

电汇格式

目前,线上格式规范中有一个关于墓碑的章节。此部分 将修改为如下内容:

Epitaph (Control Message Ordinal 0xFFFFFFFF)

An epitaph is a message with ordinal **0xFFFFFFFF**.  A server may send an
epitaph as the last message prior to closing the connection, to provide an
indication of why the connection is being closed.  No further messages may be
sent through the channel after the epitaph.  Epitaphs are not sent from clients
to servers.

When a client receives an epitaph message, it can assume that it has received
the last message, and the channel is about to be closed. The contents of the
epitaph message explain the disposition of the channel.

The epitaph contains an error status.  The error status of the epitaph is stored
in the reserved uint32 of the message header.  The reserved word is treated as
being of type **zx_status_t**: negative numbers are reserved for system error
codes, positive numbers are reserved for application error codes, and ZX_OK is
used to indicate normal connection closure.  The message is otherwise empty.

源语言

源语言规范目前有一个部分 墓碑。 我们会相应地对其进行更新。

一级语言绑定

实现应考虑到以下事实:如果发送墓碑消息, 应该是关闭前的最后一条消息 对不同语言的处理方式不同(例如,通过传递错误信息, C/C++ 中的代码,Result<t, e="">。</t,>

我们将向 C 绑定添加一个 fidl_epitaph_write(channel, zx_status_t) 方法, 以及 fidl_epitaph_t 类型。

我们会将以下文档添加到关于原始数据的部分的 C 绑定中, 绑定:

fidl_epitaph_write

Declared in lib/fidl/epitaph.h, defined in epitaph.c.

This function sends an epitaph with the given error number down the given
channel.  An epitaph is a special message, with ordinal 0xFFFFFFFF, which
contains an error code.  The epitaph must be the last thing sent down the
channel before it is closed.

C 变更的 CL:https://fuchsia-review.googlesource.com/c/zircon/+/178250

我们将更改 C++ 绑定以执行以下操作:

fidl::Binding 会在收到墓碑后立即关闭通道。

开发者将能够使用 fidl::Binding::Close 关闭频道

错误代码将使用 set_error_handler().我们将添加一个新的 error_handler 变体,该变体接受一个 该闭包会接受表示错误代码的 int 变量,并移除 现有项目可能的未来工作涉及设置“合理的默认值”错误 处理程序,但目前还不清楚这是什么。

此频道中的任何待处理读取操作都将返回 ZX_ERR_PEER_CLOSED

用于 C++ 绑定的 CL:https://fuchsia-review.googlesource.com/c/garnet/+/177939

其他绑定需要更新,包括 Dart、Rust 和 Go。

文档和示例

我们将按照上一部分中的说明更新本文档。

面向开发者的指南

摘要的目的是让服务器能够提供 就渠道的处置方式和请求向客户提供 所有可能正在进行中的作业

本部分介绍了墓碑的预期行为和用法。

  1. 墓记消息只能从服务器发送至客户端,绝不会 其他方向如果发送,它必须是服务器向 发送的最后一条消息 在服务器关闭通道末端之前触发。

  2. 当客户端收到墓记消息时,必须立即关闭其末尾 频道本身它不得试图从 可能是由不符合要求的服务器实现发送的。

  3. 如果客户观察到对等设备已关闭,但未收到纪念词条,则 它必须像收到了 ZX_ERR_PEER_CLOSED 墓碑一样继续; 这两种状态在语义上是等效的。

  4. 服务器应在 ZX_OK 关闭 但这是我们预料到的,协议达到 成功结束状态

    a. 示例:当客户端在表示 单个数据库事务,服务器应尝试将 请求的更改。如果成功,服务器必须发送 ZX_OK 墓碑 然后再关闭渠道末尾客户可基于合理理由解释 ZX_OK 摘要表示交易已成功 投入。

    b. 反例:许多协议未指定成功结束 州;客户端预期能够连接到服务器并发出一个 无限制的请求数量,直到 客户端会自行关闭渠道的一端。在这种情况下, 服务器关闭通道末端的行为构成了异常结束状态, 服务器绝不应发送 ZX_OK 摘要。

  5. 服务器可以在关闭其末尾之前发送非 ZX_OK 墓碑 除协议外的其他任何原因均可达到指定的 成功结束状态。我们建议采用以下惯例:

    a. 如果服务器因为客户端向它发送了 格式错误的 FIDL 消息,应发送 ZX_ERR_INVALID_ARGS 摘要。

    b. 如果服务器因为客户端向它发送 请求的状态是无效的,那么它应该发送 ZX_ERR_BAD_STATE 墓碑。

    c. 在客户端时,如果无法访问服务器(例如无法启动) 尝试通过服务发现机制进行连接, 应发送 ZX_ERR_UNAVAILABLE 墓碑。(另请参阅此草图。)

    d. 如果服务器由于 没有响应客户端执行的操作(例如,关闭或 内存不足时),则无需发送任何墓碑。客户端将 请按上述说明将其视为 ZX_ERR_PEER_CLOSED

    e. 如果服务器遇到应用程序特定错误,它应该发送 应用定义的错误代码。例如,如果服务器控制 而用户尝试执行其无权执行的写入 它可能希望关闭连接并报错。

    f. 此列表仅列出了部分情况。服务器可能会将其他错误 适当的选择。像往常一样,我们建议 FIDL 作者在 其协议可能返回的错误,包括 epitaphs。

向后兼容性

目前,FIDL 文档指出 0x80000001 是 墓碑。我们将其更改为 0xFFFFFFFF,因为 IO 正在使用 0x80000001。 目前没有任何设备依赖于使用 0x80000001 的墓碑。否则, 不存在向后兼容性问题

性能

不适用

安全

不适用。

测试

此功能的单元测试将添加到相应的 FIDL 绑定中。更新后 每个受支持的 FIDL 绑定都得到支持,我们应该扩充 FIDL 兼容性测试

缺点、替代方案和未知问题

我们考虑过创建一个包含 EpitaphSystem 接口 事件,该事件将是所有其他接口消息的父项。墓碑,已开启 也不能保证进行如此大的更改。目前还有两个 是解决这一问题的关键。首先,派生类型目前无法使用, 不过这种情况应该很快就会发生变化其次,由于此提案 运行时,FIDL 解析器 / 生成器依赖于运行时, 并尝试在运行时使用它会导致循环 依赖项。

此 FTP 导致的 API 更改不会阻止 Epitaph 支持 不会移至以后的系统邮件中。

有一个想法浮出水面,希望在来源中纳入一些墓碑处理法 语言,从而允许将 zx_status 标志映射为 FIDL 定义的枚举。 这可推迟到日后的工作。

建议的实现少儿不宜。如果一个会话串撰写了一条消息 与关闭通道的另一个线程同时执行,则可以写入墓记 在另一个线程的消息之前,但在对 zx_handle_close()。替代方案包括锁定频道或提供 显式系统调用。我们先从线程不安全版本开始 从而进一步加深我们对问题领域的理解。