本页尚未翻译,当前显示英文版本。
Social
Social 只增加一个概念:两个主体之间的关系,它有自己的状态和发起方。 氏族、公会或小队是一个群组,上面叠加一层关系,而不是另一种东西;屏蔽功能有多个模块需要,所以放在这里,由唯一的位置负责。
何时使用
- 玩家需要按名字找到彼此:好友、粉丝、屏蔽列表。
- 氏族或公会需要加入规则:群组(group)发出的邀请、主体提交的加入申请,以及对两者的处理决定。
- 好友列表要显示谁在线:在线状态(presence) 由会话推导而来,谁能看到它由你声明的谓词决定。
- 其他模块需要知道某人是否被屏蔽:直接从这里读取该状态,而不是自己另存一份。
- 无需使用:如果要表达的是一组主体,而不是带状态的一对主体。那是群组,而每对主体建一个群组意味着数百万个两人群组,每个都有自己的生命周期和加入规则。
分工
| 主体 | 可以 | 不可以 |
|---|---|---|
player | 发起关系或关注;接受、拒绝或撤回;解除双向关系;屏蔽和取消屏蔽;读取自己的关系以及相关主体(actor)的在线状态;订阅变更;提交加入申请 | 读取任何其他人的关系列表,无论彼此是何种参与者关系 |
moderator | 在持有成员管理原子权限的群组中,处理邀请和加入申请 | 处理自己没有权限的意向——返回 forbidden |
模型
关系声明包含的内容。
| 声明项 | 含义 |
|---|---|
kind | 对称——双方都同意才成立,下面的状态机描述的就是它;或者单向—— 即关注(follow),唯一的状态是 active。两种类型都保证每对主体唯一,且发起请求是幂等的 |
再次邀请规则 | 被拒绝之后:禁止 · 声明的时长过后允许 · 立即允许。需要声明,因为“能否再问一次”是产品决策 |
在线状态可见性 | 一个谓词——对所有人 · 仅对互相关联的主体 · 对任何人都不可见。没有默认值 |
加入方式(在群组类型上) | 开放 · 申请后审批 · 仅限邀请 |
已拒绝和已解除关系的保留 | 超过声明的时长后关系会删除,此后无论再次邀请规则如何,都可以重新邀请 |
对称关系的状态。
| 状态 | 含义 |
|---|---|
proposed | 发起方已发出请求,另一方尚未回应 |
mutual | 双方都同意 |
declined | 另一方拒绝。关系会保留,因为再次邀请规则需要知道这一点 |
broken | 一方退出了双向关系 |
blocked | 一方屏蔽了另一方 |
所有关系都成立的规则。
| 始终成立 | 含义 |
|---|---|
每对主体一个实体 | 而不是两条互为镜像的记录。“A 向 B 发出请求”和“B 收到 A 的请求”是从两边读到的同一个事实 |
发起方 | 需要声明:谁发起了请求——显示和再次邀请规则都需要它 |
屏蔽优先 | 从该状态无法转换到 proposed 或 mutual |
屏蔽 | 控制上不对称,效果上对称:只有设置屏蔽的一方能解除,而屏蔽对双方都生效 |
屏蔽状态 | 归这里所有,由其他模块使用:Messaging 等模块读取它;它们都不修改它,也都不保留副本 |
在线状态 | 由会话推导:没有人写入它,可见性谓词按请求方应用,而不是对每个主体只应用一次 |
待处理的意向 | 不占用席位(seat):邀请或加入申请从不计入群组容量,所以一百个申请也占不满一个五十人的氏族 |
群组 | 始终保有管理员:至少一个主体必须持有成员管理原子权限,最后一个 管理员不能直接离开:最后一个管理员走掉的氏族,将再也无法接纳任何人 |
群组内没有角色 | “氏族军官”是持有某个原子权限的主体,而不是列表中存储的一个等级 |
导入从不覆盖 | 从登录提供方导入的关系只做增量合并:被屏蔽的人不会因为提供方说是好友就变成好友 |
错误
- 已经是双向关系属于冲突;没有可发起的请求。
- 向自己发起请求属于校验拒绝。
- 某一方已屏蔽时返回 not found——而不是 forbidden,因为区分两者的拒绝会暴露屏蔽。重试没有意义。
- 在截止时间之前再次邀请属于冲突,截止时间过后值得重试。
- 限额用尽——关系数、意向数——属于冲突,而不是禁止:权限仍然持有,只是没有剩余容量。等有空位释放,或现有意向处理完毕后再重试。
- 意向已过期属于冲突:创建新的意向,而不是重试旧的。
- 群组最后一个管理员离开属于冲突,直到权限移交给他人。
- 没有权限却处理别人的意向返回 forbidden,重试没有意义。
- 从未连接的提供方导入返回 unavailable:以退避方式重试。
限制
具体数值会随平台限制一章给出;触及每个上限时的行为现在已经确定。
- 每个主体的双向关系数:新请求作为冲突拒绝;从不为了腾出空间解除 现有关系。
- 每个主体的单向关系数:拒绝新增关系;现有关系保留。
- 发出的请求数:拒绝新请求,而且不会淘汰旧请求:淘汰掉的邀请看起来和被拒绝的一样。
- 每个主体的屏蔽数:新增屏蔽作为冲突拒绝,旧的屏蔽不会淘汰,所以不会有人被悄悄解除屏蔽。
- 意向的有效期:变为
expired,并发出事件。 - 每个主体发起请求的频率:带截止时间的限流。
- 流中在线状态变更的频率:受更新频率约束,而不是靠丢弃变更。
- 已拒绝和已解除关系的保留期:按声明的时长删除。