go - 如何同时优化大型递归任务
问题描述
我有一个 chron 任务来执行 Golang 中的最佳方式。
- 我需要将来自 Web 服务的大数据以 JSON 格式存储在
sellers
- 将这些保存
sellers
在数据库中后,我需要浏览另一个带有sellersID
参数的大型 JSON Web 服务以保存到另一个名为customers
. - 每个
customer
都有一个初始状态,如果这个状态已经从 web 服务的数据(n°2)发生变化,我需要将差异存储在另一个表changes
中以获取更改历史记录。 - 最后,如果更改等于我们的条件,我将执行另一项任务。
我目前的操作
var wg sync.WaitGroup
action.FetchSellers() // fetch large JSON and stort in sellers table ~2min
sellers := action.ListSellers()
for _, s := range sellers {
wg.Add(1)
go action.FetchCustomers(&wg, s) // fetch multiple large JSON and stort in customers table and store notify... ~20sec
}
wg.Wait()
- 这段代码的第一个困难是我无法控制对 web 服务的调用次数。
- 第二个是该
action.FetchCustomers
函数做了很多我认为可以以并发方式完成的工作。 - 第三个难点是在出现错误的情况下无法恢复发生错误的地方。
我需要每小时运行一次此代码,因此它需要构建良好,目前它可以工作但不是最好的方式。我认为像这个例子一样考虑在 Go 中使用 Worker Pools Go by Example: Worker Pools但我很难想象它
解决方案
不要成为一个混蛋!但我会为这种事情使用队列。我已经创建了一个库并使用它。github.com/AnikHasibul/queue
// Limit the max
maximumJobLimit := 50
// Open a new queue with the limit
q := queue.New(maximumJobLimit)
defer q.Close()
// simulate a large amount of jobs
for i := 0; i != 1000; i++ {
// Add a job to queue
q.Add()
// Run your long long long job here in a goroutine
go func(c int) {
// Must call Done() after finishing the job
defer q.Done()
time.Sleep(time.Second)
fmt.Println(c)
}(i)
}
//wait for the end of the all jobs
q.Wait()
// Done!
推荐阅读
- tomcat - Apache Tomcat 服务器在注销时关闭
- python-3.x - 使用 aiohttp 创建非阻塞 RESTful 服务
- scala - scala.util.Try 递归函数抛出编译错误
- javascript - 如何将类构造函数的前一个实例的参数传播到另一个实例
- c# - Unity:卡住,当一轮完成时准确告诉 GameManager 的问题(所有敌人被杀死)
- c# - 高效快速地读取 Windows 日志
- javascript - 使用无效数据调用的函数 DocumentReference.set()。不支持的字段值:未定义(在字段 firstName 中找到)
- python - 如何通过带有图片的 HTML 重新创建网页
- ansible - Azure Stack 和 Ansible
- javascript - 检测新的鼠标滚轮事件