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.goworker.go
  • gopool.go 文件定义了 goroutine 池的主要结构和方法,包括创建 goroutine 池、添加任务、等待任务完成、释放资源等。
  • worker.go 文件定义了工作 goroutine 的主要结构和方法,包括启动工作 goroutine、执行任务、处理任务结果等。
  • 当前的 goroutine 池使用 exitChan 来控制 goroutine 的退出。

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

  1. goPool 结构中,将 exitChan 替换为 ctx context.Contextcancel context.CancelFunc
  2. NewGoPool 函数中,使用 context.WithCancel(context.Background()) 创建一个可取消的 context,并将返回的 context 和 cancel 函数存储到 goPool 结构中。
  3. Release 函数中,调用 cancel 函数来取消 context,从而通知所有的 goroutine 退出。
  4. 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)的更多相关文章

  1. .NET平台开源项目速览(21)Cron任务调度CronNET

    如果用知乎,可以关注专栏:.NET开源项目和PowerBI社区 Quartznet大名鼎鼎应该很少有人不知道,相关的开源项目很多,不过那东东对新手来说,有点晦涩,加上哪个Cron表达式,可能一进去云里 ...

  2. [GitHub]第六讲:开源项目贡献流程

    Github 是目前世界上最大的开源项目的托管交流平台.贡献开源项目的流程也是 Github 全力支持的,也一样是遵循 Github Flow,虽然跟前面团队合作流程会有一点差别.在团队内部,大家都是 ...

  3. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  4. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  5. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  6. iOS、mac开源项目及库汇总

    原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499    iOS每日一记------------之 中级完美大整理 iOS.m ...

  7. iOS、mac开源项目及库(感谢原作者的分享)

    目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...

  8. 开源项目AndroidReview学习小结(1)

    多看多学涨姿势 最近学习了一个开源项目,感觉收获颇多,这里做下简要的记录,首先感谢作者的开源.先看个大概图 感觉框架非常简单,界面也很一般,不过底层的处理的一些处理还是有很多可圈可点之处,代码的处理一 ...

  9. 如何参与flink开源项目

    参与flink开源项目 https://flink.apache.org/how-to-contribute.html 1.回答社区问题 2.撰写bug报告 3.对于改进建议或新的特征 4.帮助别人并 ...

  10. 转帖:向开源项目贡献源码(以 Orchard 为例)

    原文地址:http://yangw80.blog.163.com/blog/static/247518002201552692516908/ 在开源项目满天飞的时代,仅仅把开源项目拿来用是不够的,要适 ...

随机推荐

  1. golang在编程语言排行榜上排名第10,请不要说golang已死。

    四月头条:编程语言 Zig 进入 TIOBE 指数前 50 名 最近,我们讨论了高性能编程语言的出现.由于需要处理的数据量越来越大,这些编程语言正在蓬勃发展.因此,C 和 C++ 在前十名中表现良好, ...

  2. 2021-06-29:在两个都有序的数组中找整体第K小的数。

    2021-06-29:在两个都有序的数组中找整体第K小的数. 福大大 答案2021-06-29: 1.A和B长度不等的时候,需要把A和B的长度变成相等. A是短数组,B是长数组. 第k小的数,k从1开 ...

  3. Vue入门浅析

    title: vue入门浅析 author: Sun-Wind date: May 14,2022 写这篇博文的目的在于为初学vue的同学对vue有一些更进一步的了解 读这篇博文前,您应该至少安装了v ...

  4. < Python全景系列-2 > Python数据类型大盘点

    <Python全景系列-2> Python数据类型大盘点 欢迎来到我们的系列博客<Python全景系列>!在这个系列中,我们将带领你从Python的基础知识开始,一步步深入到高 ...

  5. 从GFS到GPT,AI Infra的激荡20年

    ​导读 最近AIGC和LLM的浪潮层层迭起,大有把AI行业过去十年画的饼,一夜之间完全变现的势头.而 AI Infra (构建AI所需的基础设施),也成了讨论的焦点之一.大众对AI Infra的关注点 ...

  6. PyQt5入门之QLineEdit

    QLineEdit:输入单行文本 下面描述了默认的键绑定.行编辑还提供了一个上下文菜单(通常通过单击鼠标右键进行调用),它提供了其中一些编辑选项. 按键 动作 Left Arrow 将光标向左移动一个 ...

  7. PHP反序列化常用魔术方法

    PHP反序列化 php序列化(serialize):是将变量转换为可保存或传输的字符串的过程 php反序列化(unserialize):就是在适当的时候把这个字符串再转化成原来的变量使用 PHP反序列 ...

  8. Dashboard监控页面和Zuul路由网关

    Dashboard监控页面 dashboard监控功能:我们需要前端页面能够监控提供者provider8001的工作状态 对dashboard监控页面的介绍: 1.在客户端导依赖 <?xml v ...

  9. [abc279 G] At Most 2 Colors

    G - At Most 2 Colors (atcoder.jp) 重点讲解方法三,因为方法三是蒟蒻都能想出来的方法一和方法二都可以借助方法三的思想推出 方法一 这是最简单的设置状态的方法,\(dp[ ...

  10. 代码随想录算法训练营Day15 二叉树| 层序遍历 10 226.翻转二叉树 101.对称二叉树 2

    代码随想录算法训练营 代码随想录算法训练营Day15 二叉树| 层序遍历 10 226.翻转二叉树 101.对称二叉树 2 层序遍历10 题目链接:层序遍历10 给你二叉树的根节点 root ,返回其 ...