JS 装饰器,一篇就够

原文地址

相关历史

三年多以前,Yehuda Katz 首先提出了装饰器的概念。TypeScript 在 1.5 版本(2015)中发布了对装饰器的支持以及许多 ES6 的相关特性。 一些主流框架,如 Angular 和 MobX 等开始使用它们来增加开发者体验:这使得装饰器非常受欢迎,并给社区带来了一种已经稳定的错觉。

Babel 第一次实现装饰器是在 v5 版本中,但由于该提案仍在不断变化,则在 Babel v6 中移除了它们。Logan Smyth 创建了一个非官方的插件(babel-plugin-transform-decorators-legacy),它延用了 Babel 5 中装饰器的行为;在 Babel 7 的 alpha 版本发布期间该库被移至 Babel 官方的仓库中。当时该插件仍使用旧的装饰器语法,因为新提案尚未明确。

自那时起,Daniel Ehrenberg、Brian Terlson 以及 Yehuda Katz 就一起成为了该提案的共同作者,该提案几乎已被完全重写。当然并非一切事情都已确定,因为至今尚未出现符合规范的实现方式。

Babel 7.0.0 为 @babel/plugin-proposal-decorators 插件引入了新的标识:legacy 选项,其唯一有效值为 true。这种突破性变更是必要的,它为提案从第一阶段到当前阶段平稳过渡作铺垫。

在 Babel 7.1.0 中,我们引入了对这个新提案的支持,并且当 @babel/plugin-proposal-decorators 插件被使用时,默认启用。而在 Babel 7.0.0 中如果我们不设置 legacy: true 选项,默认情况下就不能使用该语义(相当于 legacy: false)。

新提案同时支持使用装饰器实现私有字段(private fields)和私有方法(private methods)。我们尚未在 Babel 中实现此功能(在每个 class 中使用装饰器或私有元素),但我们会很快去出现它。

装饰器函数相关参数

新提案提出的第三个重要变化与传递给装饰器函数参数相关。

在提案的第一个版本中,类元素装饰器接收的参数分别为目标类(或对象),key 以及属性描述符 - 与传递给 Object.defineProperty 的形式类似。类装饰器将目标构造函数(constructor)作为唯一参数。

新的装饰器提案更加强大:元素装饰器会接收一个对象,该对象除更改属性描述符外,还允许更改 key 值,可以赋值(static,prototype 或者 own),以及元素的类型(field 或 method)。它们还可以创建其他属性并在装饰类上定义运行函数(完成器)。

类装饰器接收一个包含类描述符的对象,使得类在创建之前修改它们成为可能。

超越“双十一” | ebay支付核心账务系统架构演进之路

原文地址

ebay支付新一代核心账务系统FAS(Financial Accounting System)自今年3月上线以来,帮助全球百万卖家处理交易合计超百亿条,日均实时处理线上千万支付流量,每日payout金额超千万美元。系统上线至今稳定运行,并成功做到“三无”:无一次数据丢失,无一次转账错误,无一次整体宕机。系统后台仅由5台普通计算机组成,对硬件资源要求极低,且几乎无需运维。本文旨在介绍该系统背后的架构演进,希望为大家解决同类问题提供一种不一样的思路。

参考文献:

[1]https://raft.github.io/
[2]https://martinfowler.com/bliki/DomainDrivenDesign.html
[3]https://martinfowler.com/eaaDev/EventSourcing.html
[4]https://rocksdb.org/
[5]https://github.com/Netflix/chaosmonkey
[6]https://github.com/eBay/Gringofts

Raft算法

原文地址

拜占庭将军问题是分布式领域最复杂、最严格的容错模型。但在日常工作中使用的分布式系统面对的问题不会那么复杂,更多的是计算机故障挂掉了,或者网络通信问题而没法传递信息,这种情况不考虑计算机之间互相发送恶意信息,极大简化了系统对容错的要求,最主要的是达到一致性。

针对简化版拜占庭将军问题,Raft 解决方案类比

假设将军中没有叛军,信使的信息可靠但有可能被暗杀的情况下,将军们如何达成一致性决定?

Raft 的解决方案大概可以理解成 先在所有将军中选出一个大将军,所有的决定由大将军来做。选举环节:比如说现在一共有3个将军 A, B, C,每个将军都有一个随机时间的倒计时器,倒计时一结束,这个将军就会把自己当成大将军候选人,然后派信使去问其他几个将军,能不能选我为总将军?假设现在将军A倒计时结束了,他派信使传递选举投票的信息给将军B和C,如果将军B和C还没把自己当成候选人(倒计时还没有结束),并且没有把选举票投给其他,他们把票投给将军A,信使在回到将军A时,将军A知道自己收到了足够的票数,成为了大将军。在这之后,是否要进攻就由大将军决定,然后派信使去通知另外两个将军,如果在一段时间后还没有收到回复(可能信使被暗杀),那就再重派一个信使,直到收到回复。

………………

小总结

Raft 是能够实现分布式系统强一致性的算法,每个系统节点有三种状态 Follower,Candidate,Leader。实现 Raft 算法两个最重要的事是:选主和复制日志

参考链接:

Raft 官网:https://raft.github.io/

Raft 原理动画 (推荐看看):http://thesecretlivesofdata.com/raft/

Raft 算法解析图片来源:http://www.infoq.com/cn/articles/coreos-analyse-etcd

如果 Safari 做不到对,快有何用?

一个困扰了一周的 bug

2016 年的一天,当我们发现 iPhone 上的浏览器不能正确通过我们的 CDN 鉴权后,我们花了数天的时间来 debug。简单来说当时的情况是,我们需要同时上传 3 个文件,我们会用用户 token 来换 3 个独立的随机数 id,这三个 id 会被 CDN 服务器认为合法,用户可以直接上传到 CDN 上而无需在我们自己服务器上中转。
但 iOS 用户很快就出现了一个奇怪的问题,用户 3 个文件只能成功上传 1 个,剩下 2 个无法正常上传。再进一步调试后我们发现,在上传任意一个文件后,剩下两个 id 变成了非法。再进一步地,我们发现 Safari 获得的 3 个 id 竟然是完全相同的?!
复现
我很快设计出了能够构建出这个问题的重现:

原文链接