让 GPT-4 给开源项目 GoPool Review 社区贡献者的 PR - 每天5分钟玩转 GPT 编程系列(5)

来源:博客园 2023-08-09 18:33:01
目录1. 嘚瑟一下2. 言归正传2.1 GoPool 的第一个 PR2.2 祭出 GPT-42.3 问问 GPT-4 怎么看这个 PR2.4 让 GPT-4 重构代码3. 打完收工1. 嘚瑟一下

你还记得那个宣称自己性能全网第一的 Golang Worker Pool 不?对,就是能够 GoPool,据说作者拿着 GPT-4 只花了3天就把这个项目肝出来了。


【资料图】

“那个人”发的介绍 GoPool 的文章:

《仅三天,我用 GPT-4 生成了性能全网第一的 Golang Worker Pool,轻松打败 GitHub 万星项目》

真的是,都不知道谦虚一下。这种文章能不被喷?能不被质疑?这篇文章发出去一周内累计阅读量破3万了,我看 GitHub 上 GoPool 项目的小星星也奔着100去了,而且开始有人提 Issue,提 PR 了……

等等,你问我为什么知道多少人质疑,为什么知道累计3万阅读量?咳咳,我就是“那个人”,我还能不知道。哈哈哈哈……

另外确实有过个别质疑,不过都没能真的拿出代码来 PK 掉 GoPool;有时候我真想说:talking is cheap, show me the code.

2. 言归正传

聊聊发生了啥。

2.1 GoPool 的第一个 PR

今天 GoPool 收到了第一个外部贡献者的 PR:

Notify adjustWorkers to exit to prevent ticker resource leak

他也给 GoPool 提了第一个 issue:

adjustWorkers is not notified on exit, thus potential resource leak

怎么回事呢,其实是他发现了 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 maximumnewWorkers := 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 minimumremoveWorkers := 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 > 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.goworker.gogopool.go文件定义了 goroutine 池的主要结构和方法,包括创建 goroutine 池、添加任务、等待任务完成、释放资源等。worker.go文件定义了工作 goroutine 的主要结构和方法,包括启动工作 goroutine、执行任务、处理任务结果等。当前的 goroutine 池使用 exitChan来控制 goroutine 的退出。

接下来,我们将使用 context.Context来替换 exitChan,以更优雅地控制 goroutine 的退出。我们需要做以下修改:

goPool结构中,将 exitChan替换为 ctx context.Contextcancel 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 gopoolimport ("context""sync""time")type goPool struct {// ...ctx    context.Contextcancel 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:

Refactor goroutine pool to use context for graceful exit

就这样,在首位社区贡献者 oliver258 的提点下,外加 GPT-4 的帮助,GoPool 优雅地完成了一次 bugfix。

关键词:

Copyright @  2015-2022 中国99新科技版权所有  备案号: 沪ICP备2022005074号-4   联系邮箱:58 55 97 3@qq.com