漩涡的周报

Archive

2023-09: 我是如何构建 backon 的?

backon 是一个 Rust 错误重试库,今天这篇文章旨在跟分享我在实现它的过程中一些技巧~

缘起

OpenDAL 实现 RetryLayer 时需要提供一种 backoff 机制,以实现指数退避和 jitter 等特性。虽然我已经通过简单的搜索找到了 backoff,但我并不十分满意。首先,我注意到这个库的维护状况似乎不太好,有 4 个未合并的PR,而且主分支上一次更新是在 2021 年。其次,我不喜欢它提供的API:

async fn fetch_url(url: &str) -> Result<String, reqwest::Error> {
    retry(ExponentialBackoff::default(), || async { fetch().await }).await
}
#28
March 3, 2023
Read more

2023-07: 一些里程碑

这一期的周报简单总结一下最近开源工作上的一些进展和对未来的展望~

Rebirth of Sccache

在 @sylvestre 的邀请下,我成为了 Sccache 的维护者之一。

在过去的三个月中,我主要做了以下贡献:

#27
February 20, 2023
Read more

2023-06: OpenDAL 的文档即代码实践

最近做了一个很有趣的尝试,将 OpenDAL 的用户文档彻底合并到代码中,不再区分单独的用户文档和 API 文档。经过几个版本的迭代,我发现这个实践效果确实很不错,今天这篇文章主要就是分享为什么要把文档视为代码,它的好处都有哪些以及在 Rust 项目中该如何执行。

问题

OpenDAL 是一个使用 Rust 开发的数据访问库,用户通过使用 OpenDAL 就能实现与各种存储服务的集成。为了能够更好的帮助用户快速上手,OpenDAL 在 API 文档之外还维护了一份用户文档,里面的内容包括概念介绍,样例,常见用法以及内部的一些实现介绍等等。OpenDAL 使用 mdbook 来构建这份用户文档,并使用 rustdoc 来生成 API 文档,通过同一个域名的不同路径对外提供服务:

  • https://opendal.databend.rs -> 用户文档
  • https://opendal.databend.rs/opendal/ -> API 文档
#26
February 12, 2023
Read more

2023-04: 为什么你该试试 Sccache?


categories: Daily date: 2023-01-25T01:00:00Z title: “2023-04: 为什么你该试试 Sccache?”


Sccache 是由 mozilla 团队发起的类 ccache 项目,支持 C/CPP, Rust, nvcc 等语言,并将缓存存储在本地或者云存储后端。在 v0.3.3 版本中,Sccache 加入了原生的 Github Action Cache Service 支持;在后续的 v0.4.0-pre.6 版本中,社区对该功能进行了持续的改进,目前已经初步具备了在生产 CI 中应用的能力。

#25
January 28, 2023
Read more

2022 年度总结: 我的多重宇宙

今年的工作和生活都发生了很大的变化,感觉自己像是穿梭在多重宇宙中。大多数时候充满了焦虑与不安,但是又穿插着些许平淡与甜蜜,总得来说还算过的不错。相比于在过去的一年中失去了太多东西的人们,我应当感到知足与幸运。

代码

今年加入了 Datafuse Labs,开始了我全职开源的第一年。

#24
January 1, 2023
Read more

2022-50: Sccache 和 OpenDAL 的故事

最近特别开心!

在周报 2022-45: 使用 sccache 加快 Rust 编译速度 的末尾,我提到希望能把 sscache 的存储后端替换为 opendal:

我给上游提交了一个 proposal: Use opendal to handle the cache storage operations,看看能不能把 sccache 的存储后端访问改为使用 opendal,这样对接存储和调试起来就更方便了~

现在它成真了!今天这篇周报就聊一聊 Sccache 和 OpenDAL 的故事。

#23
December 15, 2022
Read more

2022-47: Databend 文档的 i18n 实践

Databend 的社区官网使用 Docusaurus 构建,托管在 Vercel 上,并使用 Crowdin 进行自动化的 i18n。

这套 SaaS 服务栈有如下好处:

  • 源代码中只需要维护源文件,不需要额外存放翻译后的文件
  • 翻译与源文件始终保持一致,不需要处理过期的翻译等问题
  • 关注点分离,编写文档与翻译的同学可以并行展开工作
  • 无额外学习成本,配置完成后翻译同学可以快速上手,无需学习命令行工具
  • 充分利用机器学习的发展来就降低工作量

今天这一期的周报主要介绍 Databend 文档基于这些服务的 i18n 实践。

#22
November 29, 2022
Read more

2022-46: OpenDAL 的错误处理实践

最近在为 OpenDAL 实现新功能的时候越来越感觉现有的错误处理逻辑能力捉襟见肘,于是花了不少时间重新设计了一套全新的错误处理逻辑。今天这篇周报就跟大家分享一下我在 OpenDAL 中的错误处理实践,希望为大家在 Rust 中构建自己的错误处理体系提供一些思路。

上下文

任何实践都不能脱离具体的场景。

在开始介绍实践之前,先了解一下 OpenDAL 这个项目以及他需要处理的哪些错误。OpenDAL 是一个旨在实现自由、无痛、高效访问数据的 Rust 库,用起来大概是这样:

#21
November 22, 2022
Read more

2022-45: 使用 sccache 加快 Rust 编译速度

sccache 是由 mozilla 开发的编译缓存工具,设计思路是作为一个编译的 wrapper,把编译产物放在保存到存储后端上,尽可能避免重复编译,从而加快整体的编译速度。sccache 支持的编译后端包括 gcc, clang, MSVC, rustc, NVCC 等等。以 Rust 编译为例,可以这样来使用它:

export RUSTC_WRAPPER=/path/to/sccache
cargo build

最近社区提出有没有办法加快 databend 的编译速度,我想到了可以使用 sccache 来加速,优势如下:

  • Databend 依赖众多,而大部分依赖很少会变化,他们都能够被很好的缓存下来
  • Databend 的 dev 构建跑在 AWS 的 Self-hosted Runner 上,而且本身就已经配置好了内网的 S3 bucket
#20
November 15, 2022
Read more

2022-44: 流浪小猫与自由长毛象

流浪小猫

寒冷冬夜,遛狗路上。

我们突然听到一阵凄切的猫叫声,我爱人循着叫声过去,发现是一只刚断奶的一月龄小猫。小猫不是很怕人,而且全身特别干净,没有异味,我爱人判断这是一只家养的猫。随后对它做了快速的检查,发现腿脚正常,五官正常,没有明显的病理症状。检查中还发现它的肚子是鼓鼓的,应该是刚吃完饭,这进一步推断出这只小猫是被遗弃的。一般来说,猫妈妈不会离刚断奶的小猫这么远,而且这里是一处毗邻很多小区的路边公园,可能是被主人遗弃的。说主人没良心吧,他把小猫刚刚好养到了断奶期,而且还喂饱了饭扔了;说主人有良心吧,他也不能干出凌晨十二点扔猫的事儿。由于担心小猫晚上被直接冻死,我们决定先把小猫带回家然后再决定下一步行动。

回家之后把两个狗都隔离起来,避免他们之间的接触。因为猫狗之间存在传染病,除此以外,还要考虑真菌/细菌/跳蚤之类的问题。所以在确认小猫的身体状况之前,我们要把家里的原住民隔离开。我们虽然一直都有想养猫(缅因)的计划,但一直都没有付诸于行动(家太小了),所以很多用具都简单代替一下。没有猫窝,我们弄了一个大纸箱,里面放上了一些软布;没有猫砂,我们用一个狗狗尿垫作为替代;没有猫粮,我们撅了几根火腿肠替代。忙活了好一阵子之后,终于把小猫安置好了。

#19
November 7, 2022
Read more

2022-43: 工作中的自我调适

出于众所周知的原因,最近几周的状态一直不太好,感觉自己的生活充满了不确定性。每天都特别焦虑地刷着新闻,在各个群中游走,重复着自己都觉得腻歪的段子,宣泄着无用的不满情绪,转发着胜利伟大正确的新闻。工作上的体现是很难定下心来开始工作,坐下来没多久就想再刷刷推特看看有没有新的好消息,侧面的体现则是我的英雄联盟手游大乱斗刷上了乱斗之王的最高级称号。

最近在我爱人的帮助下这种情况有了很大的好转,终于开始能够做一些工作并交付成果了。今天这篇周报就聊一聊我都采取了哪些措施来帮助我度过这段难捱的时间~

引入生活常量

在觉察到我的不正常之后我爱人开始积极引入生活常量,采取的措施包括:

#18
October 31, 2022
Read more

2022-42: OpenDAL Key-Value Adapter

OpenDAL 在最近的版本中增加了 Adapter 的概念,将 OpenDAL 支持的服务范围从传统的文件系统和对象存储扩展到了诸如 Redis,Moka 等 Key-Value 存储服务上。今天这篇周报就介绍一下我们为什么要增加这个抽象,它解决了哪些问题,以及社区现在的进展。

背景

OpenDAL 旨在自由,无痛,高效的访问数据,其中自由意味着 OpenDAL 可以以相同的方式访问不同的存储服务。为了实现这一点,OpenDAL 实现了不少服务的支持,比如 azblob,fs,ftp,gcp,hdfs,ipfs,s3 等等。这些服务虽然接口和实现各有各的差异,但是他们共性是都有着类 POSIX 文件系统的抽象,OpenDAL 不需要额外的抽象层就能访问其中的数据。换言之,OpenDAL 对存储底层的操作对用户来说是透明的,离开 OpenDAL 用户也可以正常访问这些数据。基于这样的设计, OpenDAL 没有考虑过支持 Key-Value 服务:因为我们无法从 Key-Value 服务中读取到任何有意义的数据,其存储的数据结构高度依赖于应用的具体实现。

但是在后续社区的多次讨论中,我们逐渐发现在 Key-Value 服务的基础上定义一个自己的存储结构,并用来实现 OpenDAL 的接口同样是有价值的。Databend 提出了这样的需求:他希望 OpenDAL 能够实现一层缓存,可以将数据存储在不同的缓存服务上,比如内存,本地文件系统和 Redis 上,他们能够设置一定的淘汰策略,自动过期。换言之,Databend 希望 OpenDAL 能够支持易失性数据的存储,他们会被用作缓存和临时的数据存储,用户不会通过其他方式(比如 awscli)来访问它。在这种场景下, Key-Value 服务是一个黑箱,用户只通过 OpenDAL 来访问。既然不需要暴露给外部访问,OpenDAL 完全可以自行决定在 Key-Value 服务上的存储结构。

#17
October 25, 2022
Read more

2022-41: Rust Drop 踩坑分享

Rust 使用 RAII (Resource Acquisition Is Initialization) 来管理资源:对象初始化会导致资源的初始化,而对象释放时会导致资源的释放。

以 Mutex 为例:

{
    let guard = m.lock();
    // do something
}
// guard freed out of scope.
{
    // we can acquire this lock again.
    let guard = m.lock();
}

当 guard 离开当前 scope 的时,rust 会保证 guard 的 drop 被自动调用:

#16
October 16, 2022
Read more

2022-38: Iteration 22 汇报

Iteration 22 从 9/12 开始到 9/25 结束,为期两周。这个周期我的主要工作是删代码:

经过了几个版本的迭代之后,Databend 已经完成了 New Executor,New Planner 的重构,目前正在进行 New Expression。伴随着对 JOIN 的正式支持等新特性的增加,Databend 的代码库也出现了比较严重的腐化现象:陈旧的代码散落在项目的各个角落,不少新的功能实现还在依赖已经被弃用的逻辑。我从清理 Old Planner 入手开始尝试缓解这个问题:最开始的计划只是想奋斗三天,删除掉对 sqlparser-rs 的依赖,但是最后发现 Databend 对它的依赖如此深入以至于这变成了跨越数个迭代周期的大型工作。

很久之前我在 Databend 中加入了 See you again: refactor: Dedicate See you again to the old planner,通过在旧的 DfStatement 中引入一个 Dummy Statement SeeYouAgain,将绝大部分操作都直接转发给了 New Planner。现在我发起了新的项目: refactor: Old Planner Never See Again (Part 1)。这个项目旨在彻底删除掉 Old Planner,将过时的代码完全清理掉。执行到 Part 2 的时候我发现事情并不简单,很多复杂的问题被交织在一起,过去因为同在一个 crate 中没有暴露出来的复杂依赖关系一下子都暴露了出来。为了能够顺利的删除掉旧代码,我被迫做了很多铺垫工作:

#15
September 25, 2022
Read more

2022-37: 基于 Github 的公开工作流程

在 2021 年度总结 中,我首次宣布了公开工作的尝试:Xuanwo’s Work。当时 Github Projects 本身在 Beta 中,缺乏周边的 API 支持,功能不完善。而且我也是首次尝试公开工作流程,因此没有过多的介绍我是如何使用,如何管理的。在九个月之后,Github Projects 终于提供了简陋的自动化支持,可以添加不属于同一个 owner 的 issue / PR,增加了基础的报表功能,作为一个任务管理工具来说功能已经基本完备。同时,我成为了 Github Projects 专家,掌握了绝大多数技巧。

因此今天这篇文章就跟大家分享一下我目前正在使用的基于 Github 的公开工作流程。

元数据

Github Projects 没有提供内置的工作流程,只提供了自定义元数据的能力。

#14
September 16, 2022
Read more

2022-36: 为 OpenDAL 增加 IPFS 支持

最近在社区同学 @xprazak2 的帮助下为 OpenDAL 增加了 IPFS 支持。

具体的来说是两个 Service:

  • ipfs: IPFS HTTP Gateway 支持
  • ipmfs: IPFS Mutable File System 支持

其中,ipfs 基于 HTTP Gateway 提供了 read 和 list 支持,而 ipmfs 则基于 MFS 提供了完整的读写支持。

#13
September 8, 2022
Read more

2022-33: 电脑坏了之后

在一次 cargo bench 之后,电脑突然黑了。

问题定位

之前也突然这样关机过几次,没觉得是个事儿,喝了一口咖啡之后再次按下了开机键。但是在闪过了 Lenove 的 Logo 之后,电脑再次自动关机了。反复尝试多次后,发现连 BIOS 都进不去。这下我知道大条了,肯定有某个组件坏掉了。主板自检能过,应该不是 CPU 或者 内存的问题;闪过了 Logo 之后过一段时间就自动关机,感觉上是散热之类的问题。除此以外,启动的时候还会出现比较明显的咔啦咔啦声音,不知道具体是哪个组件坏了- -

这次电脑彻底开不了机让我想起了之前的几次小故障:每次电脑在高负载下持续运转一段时间之后出现非常严重降频,之后就会在巨大的风扇声音中自动关机。现在回想起来那个时候电脑可能就已经处于不正常的状态了,但是这次彻底挂了。

#12
August 25, 2022
Read more

2022-32: Github 实用小技巧

今天跟大家聊聊我经常使用的 Github 实用小技巧:

  • 引用 Github Issues/PR/Discussion
  • 使用 Fix / Close 来关联一个 Issue
  • 可折叠的区块
  • Draft / Ready for review
  • 请求 Review
  • 引用回复

引用 Github Issues/PR/Discussion

在 Github 的任何编辑框都可以使用 # + Issues/PR/Discussion 数字 ID 的形式来引用:

#11
August 15, 2022
Read more

2022-31: Databend 的工程效率实践

工程效率对任何工程师团队的重要性都不言而喻:优秀的工程效率实践能够帮助团队更大程度发挥潜能,更高效地进行产品迭代;而低劣的工程效率模仿往往会让团队负重前行,每天都痛苦不堪,最终在沉默中燃尽所有的热情。

出于个人兴趣,我在每家公司都参与过工程效率相关的工作:在青云的时我推动了整条存储产品线 Golang 版本管理向 Go Modules 的迁移,在参与 Databend 的过程中我重新设计了全新的 CI/CD Pipeline,完成了从自行部署的 fusebot 到完全 SaaS 化的 PR 流程迁移。今天这篇文章主要总结了我在 Databend 的工程效率实践,首先介绍 Databend 的具体实践,然后再聊聊我个人的一些心得体会,希望对其他开源项目的相关实践落地能够有所帮助。

Databend 没有专职的工程效率团队,相关实践能够落地需要感谢 @everpcpc, @ZeaLoVe 和 @PsiACE 等同学在本职工作之外的付出。


#10
August 8, 2022
Read more

2022-30: 如何维护一个开源项目

之前跟大家聊了很多如何参与一个开源项目,今天跟大家聊聊如何维护一个开源项目。

开源项目并不是代码的集合:每一个开源项目都能够视作一个小型的公司,它有自己的市场定位,有自己的战略目标,有自己的用户受众。因此开源项目维护有着大量工程以外的工作,包括但不限于跟用户沟通,设定路线图等等。本文旨在为加入开源维护者行列的新人提供一个基本的指引,讲解开源维护者应该需要做的事情。

First Day

开源维护者在开始一个项目之前,需要首先搞清楚项目的目标市场及其定位。

#9
July 31, 2022
Read more

2022-29: 在疫情期间得感冒

在这个魔幻的时代,感冒发烧的后果非常严重。

可能是游泳之后没有擦干就到处兜风,可能是回家之后贪凉狂吹了空调,我的女朋友发烧了。考虑到我们最近一直在做核酸,没有已知的阳性病例,再加上不怎么出门,所以我们非常清楚这只是普通的发烧。最开始没当做什么非常严重的事情,找了家里的退烧药吃了。但是情况并没有好转:女朋友开始疯狂咳嗽,体温在不断上升。当时已经是深夜一两点了,想着再忍忍等到白天再去医院,于是只是在家做了一些物理降温的措施,然后又吃了几片广谱抗生素。到三四点的时候,女朋友把我推醒,说自己感觉非常不好,自测体温已经 39 度了。凭借我们浅显的医学知识:体温超过 38.5 度已经非常危险,需要立即采取退热治疗。于是我们赶紧带上了冰袋,然后打了车去医院挂深夜急诊。

在空档的医院奔走半天之后,急诊的护士告诉我们有发热症状的病人需要去专门的发热门诊,而发热门诊在一个特别犄角旮旯的地方,我被迫往返了两次急诊楼才问到确切位置。等到了发热门诊我们才知道,这里是完全隔离的:病人进去后需要立即做核酸,等到核酸结果出来之后才能离开,在此期间病人只能在发热门诊里头坐着。接待的护士表示需要在里面等四到六小时左右,同时家属不允许入门。来的太匆忙,我们完全没有需要长期作战的准备。女朋友的症状有所好转,我们决定等天亮了再来,今天晚上就不在里面干熬了。

事与愿违,我们到家之后没多久女朋友的病情再度恶化,以至于太难受了,等不到天亮。我们赶紧收拾好干粮,水,充电宝等物品,再度打车来到了发热门诊。签好了一大堆材料之后,女朋友带着医用口罩进去开始隔离。做核酸,抽血,等待结果,医生接诊,最后诊断是病毒性上呼吸道感染,给出的治疗方式是低于 38.5 度物理降温,高于 38.5 度吃退烧药,药跟我们在家里吃的完全一样,除此以外就是干熬。这让我们非常愤慨:这跟我们在家里的处置有啥区别?女朋友还拖着非常难受的身体问医生能不能打针或者挂点滴,被直接拒绝了,表示只有烧到 39 度能可以打针。于是女朋友只能在黑暗的医院大堂里坐着扮演干尸,默默地等待核酸结果出来好早点回家。

#8
July 25, 2022
Read more

2022-26: 哑巴英语首次开口

Iteration 16 从 6 月 18 号开始到 7 月 3 号结束,为其两周。这个周期有意思的事情不少,其中印象最深刻就是哑巴英语首次开口的经历。

与 Mergify 的采访

Mergify 是一个 Pull Request 自动化工具,主要的功能包括 Auto Merge,Merge Queue,PR Actions 等。Databend 最早使用他来解决 PR 自动合并的问题,后来使用范围逐渐扩大,现在已经将所有的 PR 相关的自动化流程都交由 Mergify 处理。

我们使用 Merfigy 完成如下工作:

#7
July 4, 2022
Read more

2022-25: 开源当以上游优先

上游优先(Upstream First) 是开源协作中的重要理念,今天就结合实例来聊一聊为什么要采用上游优先以及上游优先该怎么做。

上游优先

软件项目不可避免地会依赖其他项目并且被其他项目所依赖,本项目的依赖叫做上游(Upstream),依赖本项目的其他项目则叫做下游(Downstream)。而在维护项目的过程中,出于各种原因,会需要对上游做出变更,常见的情况包括:

  • 上游做出了破坏性变更
  • 上游出现了一个尚未修复的 BUG
  • 上游缺乏本项目需要的功能特性
#6
June 27, 2022
Read more

2022-24: 开源,无禁止即可为

尽管我们经常说代码贡献并不是唯一的开源贡献方式,参与讨论,Review RFC 也是参与开源的良好途径。但是很多同学仍然会有疑虑:我不是项目的 Maintainer/Committer/Reviewer,我有资格 Review 别人的 PR 吗?本文以我在 envd 中的实践来阐述这样的观点:开源,无禁止即可为。


关于 envd

envd 是 tensorchord 发起的开源项目,旨在解决机器学习开发过程中环境难以部署的问题,主要团队成员包括 @gaocegege,@terrytangyuan,@kemingy,@VoVAllen 等。

#5
June 20, 2022
Read more

2022-23: 新轮子 globiter 和一些想法

这周诞生了一个很有意思的想法,如果 databend 能够支持这样的 query:

COPY INTO books
FROM 's3://databendcloud/loaddata/books.csv'
file_format = (type = 'CSV' field_delimiter = ',' record_delimiter = '\n' skip_header = 0);

那为什么不能支持这样呢?

COPY INTO books
FROM 'https://databend.rs/loaddata/books.csv'
file_format = (type = 'CSV' field_delimiter = ',' record_delimiter = '\n' skip_header = 0);
#4
June 13, 2022
Read more

2022-22: 为 Databend 实现压缩支持

Iteration 14 从 5/21 开始到 6/4 结束,为期两周。这个周期主要在做 Databend 的压缩支持,具体的来说是支持如下功能:

支持读取 Stage/Location 中的压缩文件

copy into ontime200 from '@s1' FILES = ('ontime_200.csv.gz')
FILE_FORMAT = (type = 'CSV' field_delimiter = ',' compression = 'gzip' record_delimiter = '\n' skip_header = 1);

支持流式上传压缩文件:

#3
June 6, 2022
Read more

2022-21: 远程工作的光谱

随着疫情的不断延续,远程工作已经不再是新鲜事物。对绝大多数公司和团队来说,远程工作已经不再是 Yes/No 的问题,而是选择在光谱中哪一侧的问题。最近正在处理这方面的事务,因此了解了国内社保以及公积金政策的相关情况以及公司会面临的一些取舍。今天这篇文章就跟大家聊聊远程工作的光谱,相信会对大家在挑选远程工作(尤其是大陆的职位)时有帮助,避免踩坑。

社保光谱

对在大陆求职的工程师来说,社保和公积金,也就是常说的五险一金是一个绕不开的问题,而公司如何处理往往也能凸显出他们的诚意和态度。

五险一金具体包括养老保险、医疗保险、失业保险、工伤保险、生育保险以及公积金。其中养老保险、医疗保险、失业保险和公积金由企业和个人共同承担,工伤保险和生育保险完全是由企业承担的。对应的缴纳比例如下:

#2
May 30, 2022
Read more

2022-20: Iteration 13 汇报

Iteration 13 从 5/7 开始到 5/20 结束,为期两周。这个周期成功合并了不少之前提交的 PR,感觉非常有成就感。

difftastic

difftastic 是一个使用 Rust 开发的能理解语义的 diff 工具。

在这个周期中,我合并了两个 PR:

#1
May 23, 2022
Read more
Brought to you by Buttondown, the easiest way to start and grow your newsletter.