

让 GPT-4 给开源项目 GoPool Review 社区贡献者的 PR - 每天5分钟玩转 GPT 编程系列(5...
source link: https://www.cnblogs.com/daniel-hutao/p/gpt_code_review.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1. 嘚瑟一下
你还记得那个宣称自己性能全网第一的 Golang Worker Pool 不?对,就是能够 GoPool,据说作者拿着 GPT-4 只花了3天就把这个项目肝出来了。
“那个人”发的介绍 GoPool 的文章:
真的是,都不知道谦虚一下。这种文章能不被喷?能不被质疑?这篇文章发出去一周内累计阅读量破3万了,我看 GitHub 上 GoPool 项目的小星星也奔着100去了,而且开始有人提 Issue,提 PR 了……
等等,你问我为什么知道多少人质疑,为什么知道累计3万阅读量?咳咳,我就是“那个人”,我还能不知道。哈哈哈哈……
另外确实有过个别质疑,不过都没能真的拿出代码来 PK 掉 GoPool;有时候我真想说:talking is cheap, show me the code.
2. 言归正传
聊聊发生了啥。
2.1 GoPool 的第一个 PR
今天 GoPool 收到了第一个外部贡献者的 PR:
他也给 GoPool 提了第一个 issue:
怎么回事呢,其实是他发现了 GoPool 中的这个函数没有 return 逻辑:
// adjustWorkers adjusts the number of workers according to the number of tasks in the queue.
func (p *goPool) adjustWorkers() {
ticker := time.NewTicker(p.adjustInterval)
defer ticker.Stop()
for range ticker.C {
p.cond.L.Lock()
if len(p.taskQueue) > len(p.workerStack)*3/4 && len(p.workerStack) < p.maxWorkers {
// Double the number of workers until it reaches the maximum
newWorkers := min(len(p.workerStack)*2, p.maxWorkers) - len(p.workerStack)
for i := 0; i < newWorkers; i++ {
worker := newWorker()
p.workers = append(p.workers, worker)
p.workerStack = append(p.workerStack, len(p.workers)-1)
worker.start(p, len(p.workers)-1)
}
} else if len(p.taskQueue) == 0 && len(p.workerStack) > p.minWorkers {
// Halve the number of workers until it reaches the minimum
removeWorkers := max((len(p.workerStack)-p.minWorkers)/2, p.minWorkers)
p.workers = p.workers[:len(p.workers)-removeWorkers]
p.workerStack = p.workerStack[:len(p.workerStack)-removeWorkers]
}
p.cond.L.Unlock()
}
}
也就是说在 GoPool 被 Release 的时候,并不能保证这个 adjustWorkers() 函数返回,也就是对应的 goroutine 不会退出。这个问题说大不大,因为这个 goroutine 很轻量;不过确实这也是一种“内存泄露”,这个 goroutine 总归还是被停掉更优雅。
2.2 祭出 GPT-4
在 GitHub 上看这个 PR 还是不太清晰:

一坨删除,一坨新增。懒得一行行看了,祭出 GPT-4 吧。
下文使用 DevChat 和 GPT-4 交互。如果你对 DevChat 感兴趣,可以跳转阅读这篇文章:
- 《DevChat:将 GPT-4 无缝融入 VS Code,极致提升你的编程体验》
- 如果你想要注册 DevChat,点击这个链接可以免费注册,目前 DevChat 还在公测中,不收费。
- 我问 GPT-4:
VS Code 里怎样 review GitHub 上的一个 PR?
- GPT-4 这样回答:

行吧,我装一个 GitHub 插件。第一次用,还是有点小惊喜呀,眉清目秀:

2.3 问问 GPT-4 怎么看这个 PR
我先用 git show <commit-hash> > a.diff
命令将这个 PR 的变更内容输出到 a.diff 文件中,方便告诉 GPT-4 当前 PR 的变更内容。

如图所示,我将代码和 Diff 内容都抛给了 GPT-4,让它告诉我这个修改对不对。总之 GPT-4 说这个修改没问题,我自己也肉眼看了一遍这个修改,至少,功能上是正确的。于是我先合入了这个 PR,并且对贡献者表示感谢。
2.4 让 GPT-4 重构代码
我感觉用 Context 实现 goroutine 退出会更优雅一些,不过秉承着“有事 GPT 干,没事干 GPT”的原则,于是我又问 GPT-4:
如你所见,这段代码里用了 exitChan 来控制 goroutine 的退出,我觉得用 Context 可能更优雅,对吗?如果是的话,请帮我重构代码,引入 Context 逻辑。

GPT-4 的完整回答如下:
首先,我们需要理解当前代码的主要功能和结构:
- 这是一个 Go 语言的 goroutine 池实现,主要包含两个文件:
gopool.go
和worker.go
。 gopool.go
文件定义了 goroutine 池的主要结构和方法,包括创建 goroutine 池、添加任务、等待任务完成、释放资源等。worker.go
文件定义了工作 goroutine 的主要结构和方法,包括启动工作 goroutine、执行任务、处理任务结果等。- 当前的 goroutine 池使用
exitChan
来控制 goroutine 的退出。
接下来,我们将使用 context.Context
来替换 exitChan
,以更优雅地控制 goroutine 的退出。我们需要做以下修改:
- 在
goPool
结构中,将exitChan
替换为ctx context.Context
和cancel context.CancelFunc
。 - 在
NewGoPool
函数中,使用context.WithCancel(context.Background())
创建一个可取消的 context,并将返回的 context 和 cancel 函数存储到goPool
结构中。 - 在
Release
函数中,调用 cancel 函数来取消 context,从而通知所有的 goroutine 退出。 - 在
adjustWorkers
函数中,将case <-p.exitChan:
替换为case <-p.ctx.Done():
,以便在 context 被取消时退出 goroutine。
以下是修改后的代码:
package gopool
import (
"context"
"sync"
"time"
)
type goPool struct {
// ...
ctx context.Context
cancel context.CancelFunc
// ...
}
func NewGoPool(maxWorkers int, opts ...Option) *goPool {
ctx, cancel := context.WithCancel(context.Background())
pool := &goPool{
// ...
ctx: ctx,
cancel: cancel,
// ...
}
// ...
return pool
}
func (p *goPool) Release() {
close(p.taskQueue)
p.cancel()
// ...
}
func (p *goPool) adjustWorkers() {
ticker := time.NewTicker(p.adjustInterval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// ...
case <-p.ctx.Done():
return
}
}
}
这样,我们就使用 context.Context
替换了 exitChan
,以更优雅地控制 goroutine 的退出。
3. 打完收工
这次 GPT-4 给的代码直接就能跑通,于是我追加了这个 commit:
就这样,在首位社区贡献者 oliver258 的提点下,外加 GPT-4 的帮助,GoPool 优雅地完成了一次 bugfix。
Recommend
-
57
-
35
很多从事开源人可能会注意到有些开源项目要求贡献者在提交 PR 前首先签署 CLA,只有签署了 CLA 之后 PR 才可以合并。 开源贡献协议简...
-
12
18 岁开源贡献者自杀,开发者的心理健康问题谁来关注?开源开发者有多难?我们从近期多个事件及调查结果中可见一斑。拥有数百万用户的开源项目 Babel 陷入财务困境;...
-
7
CNCF 开源项目远程带薪实习机会来啦!申请成为 WasmEdge 的贡献者吧 LFX Mentorship 2022 春季学期开始申请啦!LFX Mentorship 类似 GSoC,Linux 基金会将为参与 CNCF 开源项目的开发者提供带薪实习的机会! 为开源项目做贡献,获得开源社区的...
-
10
利用GitHub Actions自动将项目贡献者列表添加到README中原创 当我们负责的项目有越来越多的人加入进行协作之后,将贡献者添加到 README 中是一个很好的激励作用,很多大的项目也都是这么做的,本文就来讲一下,如何借助 Github Actions 自动将项目贡献者列...
-
10
GitHub 项目遭到“有毒”言论攻击,核心开源贡献者被迫出走!
-
8
【专访】 Chrome HEVC 硬解背后的字节开源贡献者 2022年10月26日 06:15 · 阅读 278
-
5
V2EX › 问与答 如何看待开源项目总是标自己的产品和作者贡献者都是大厂职工 ?
-
5
Apache Dubbo 开源社区召集 Go、Kubernetes 核心贡献者 chickenlj · 2天...
-
6
V2EX › 程序员 GitHub 用户来领空投: TOP 5k 项目的贡献者可领取价值 $200 空投
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK