让 GPT-4 给开源项目 GoPool Review 社区贡献者的 PR - 每天5分钟玩转 GPT 编程系列(5)
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 感兴趣,可以跳转阅读这篇文章:
《https://www.danielhu.cn/devchat-gpt4-vscode-integration/》
如果你想要注册 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。
让 GPT-4 给开源项目 GoPool Review 社区贡献者的 PR - 每天5分钟玩转 GPT 编程系列(5)的更多相关文章
- .NET平台开源项目速览(21)Cron任务调度CronNET
如果用知乎,可以关注专栏:.NET开源项目和PowerBI社区 Quartznet大名鼎鼎应该很少有人不知道,相关的开源项目很多,不过那东东对新手来说,有点晦涩,加上哪个Cron表达式,可能一进去云里 ...
- [GitHub]第六讲:开源项目贡献流程
Github 是目前世界上最大的开源项目的托管交流平台.贡献开源项目的流程也是 Github 全力支持的,也一样是遵循 Github Flow,虽然跟前面团队合作流程会有一点差别.在团队内部,大家都是 ...
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...
- iOS及Mac开源项目和学习资料【超级全面】
UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...
- iOS开发--iOS及Mac开源项目和学习资料
文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...
- iOS、mac开源项目及库汇总
原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499 iOS每日一记------------之 中级完美大整理 iOS.m ...
- iOS、mac开源项目及库(感谢原作者的分享)
目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...
- 开源项目AndroidReview学习小结(1)
多看多学涨姿势 最近学习了一个开源项目,感觉收获颇多,这里做下简要的记录,首先感谢作者的开源.先看个大概图 感觉框架非常简单,界面也很一般,不过底层的处理的一些处理还是有很多可圈可点之处,代码的处理一 ...
- 如何参与flink开源项目
参与flink开源项目 https://flink.apache.org/how-to-contribute.html 1.回答社区问题 2.撰写bug报告 3.对于改进建议或新的特征 4.帮助别人并 ...
- 转帖:向开源项目贡献源码(以 Orchard 为例)
原文地址:http://yangw80.blog.163.com/blog/static/247518002201552692516908/ 在开源项目满天飞的时代,仅仅把开源项目拿来用是不够的,要适 ...
随机推荐
- 文心一言 VS chatgpt (16)-- 算法导论4.1 1~2题
一.当A的所有元素均为负数时,FIND-MAXIMUM-SUBARRAY返回什么? 文心一言: 当A的所有元素均为负数时,FIND-MAXIMUM-SUBARRAY返回-1. 这是因为在二进制中,当所 ...
- 2022-09-19:给定字符串 S and T,找出 S 中最短的(连续)子串 W ,使得 T 是 W 的 子序列 。 如果 S 中没有窗口可以包含 T 中的所有字符,返回空字符串 ““。 如果有不
2022-09-19:给定字符串 S and T,找出 S 中最短的(连续)子串 W ,使得 T 是 W 的 子序列 . 如果 S 中没有窗口可以包含 T 中的所有字符,返回空字符串 "&q ...
- 2021-11-22:给定一个正数数组arr,表示每个小朋友的得分; 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果; 假设所有的小朋友坐
2021-11-22:给定一个正数数组arr,表示每个小朋友的得分: 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果: 假设所有的小朋友坐 ...
- django model字段类型
1.models.AutoField 自增列=int(11) 如果没有的话,默认会生成一个名称为id的列,如果要显示的定义一个自增列,必须把该列设置为主键(primary_key=True)2.mod ...
- python爬虫防止IP被封的一些措施(转)
python爬虫防止IP被封的一些措施(转) 在编写爬虫爬取数据的时候,因为很多网站都有反爬虫措施,所以很容易被封IP,就不能继续爬了.在爬取大数据量的数据时更是瑟瑟发抖,时刻担心着下一秒IP可能就被 ...
- 安装Visio 2016与原本的office冲突的最终解决方案
一. 下载office visio 2016 二. 开始安装 但是提示卸载原本的office 三. 网上找寻答案 于是按照这篇文章https://jingyan.baidu.com/article/1 ...
- Redash 可视化BI系统部署安装及简单使用
这篇文章主要为介绍一下Redash的使用和安装 概览 Redash 主要使用的语言为 Python 和 TypeScript 这个安装主要是基于Docker 来安装的,官网教程基本没有不是基于Dock ...
- Flutter调优--深入探究MediaQuery引起界面Rebuild的原因及解决办法
前言 我们可以通过MediaQuery.of(context)方法获取到一些设备和系统的相关信息,比如状态栏的高度.当前是否是黑暗模式等等,使用起来相当方便,但是也要注意可能引起的页面rebuild问 ...
- JavaWeb编程面试题——MyBatis
引言 面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待.不以刷题进大厂为目的,而是以学习为目的.这里的知识点会持续更新,目录也会随时进行调整. 关注公众号:编 ...
- 【Python&GIS】通过经纬度创建矢量点文件
最近在做项目时,需要判断某个点是否在感兴趣区内.所以需要使用Python先根据经纬度的点创建矢量文件,再通过点文件和面文件的位置关系判断点是否在面内. 这里我们使用osgeo ...