我想知道在包的函数中使用无限 for 循环是否是一个坏主意,或者是否应该避免这样做。init()如果可以这样做或应该避免这种情况,是否有人有任何知识或经验?你会在哪里使用这个?例如,这可以用于提供来自外部源的一些信息的包,这些信息必须定期刷新(例如每天一次)。我使用了如下类似的代码,但没有“看门狗”功能。这意味着init()刚刚启动了一个 go 例程,该例程将在后台运行,并在蜱到达时运行更新过程。不幸的是,这个更新机制在 aprox 之后停止工作。由于未知原因,3 个月了,但服务运行良好,只是使用“旧”数据。简单示例实现完整示例请参见https://play.golang.org/p/k-GI1t9J4oPpackage infoimport ( "log" "sync" "time")var ( data map[string]interface{} lock sync.RWMutex)func init() { // ticker channel ticker := time.NewTicker(1 * time.Second).C // "watchdog" loop for { log.Println("Starting Update Loop") var wg sync.WaitGroup wg.Add(1) // Start asyc update process. go func() { defer wg.Done() //notify wg when if process ends for whatever reason // Loop forever // Run when a tick is received from the `ticker` channel for { select { case <-ticker: log.Println("Update ticker received") err := update() if err != nil { log.Printf("ERROR: %v\n", err.Error()) } } } }() wg.Wait() }}// internal update function that retrieves some information from some external systemfunc update() error { lock.Lock() defer lock.Unlock() log.Println("Update `data`") // retrieve information and update `data` return nil}// Public function to query datafunc GetInformation(key string) interface{} { lock.RLock() defer lock.RUnlock() return data[key]}该代码可以正常工作并在单元测试中运行良好,并且也可以正常运行。我想知道长期稳定性(一年或更长的正常运行时间)等等。
1 回答
繁星点点滴滴
TA贡献1803条经验 获得超3个赞
它位于 goroutine 中,因此技术上没有问题,但直接在 an 中实现行为init
会使其非常难以使用,原因有两个:
测试很难,就像
main
测试很难一样。测试是否调用另一个函数要容易得多init
,然后可以对其进行测试。很难推理。“自动”发生的事情越多,对于使用该包的任何开发人员(包括未来的你)来说,它的意义就越小。“好吧,我导入了这个包并使用了一个微小的函数,现在不知怎的,我的 CPU 使用率从 1% 上升到了 50%,我做错了什么”,这样的事情将会出现,需要更多的探索才能弄清楚。
TL;DR 不存在“长期稳定性”问题,但很可能存在长期可维护性问题。
- 1 回答
- 0 关注
- 74 浏览
添加回答
举报
0/150
提交
取消