关于scheduler代码实现的几个问题

来源:5-5 task示例的实现

Schwarzeni

2019-04-13

  1. 老师您在视频 5-5 15:29 左右的时候说重复读取要删除的文件没有关系,但是 func deleteVideo(vid string) error 中删除本地文件出错是会有日志打印的,也就是可能会出现如下情况:
    goroutine A 和 goroutine B 先后执行删除文件aaa的操作,但是B要删除aaa时A已经将aaa删除了,此时B就会打印错误日志说文件不存在。
    这可能会对查看日志debug的人产生困惑,所以我觉得这个问题是必须要进行处理的

  2. 不论是将要删除视频的名称存入数据库,还是在 VideoClearExecutor 中对其进行删除的时候都没有对其在磁盘是否存在做出判断,也没有将错误的数据从数据库中删除,这会导致定时任务每执行一次就会打印一次文件不存在的日志,我觉得这个也是不太严谨的

  3. 在问题VideoClearExcutor的实现是否会出现并发问题? 中老师您回答说 for是个阻塞的死循环,只有在下面break之后才会跳出, 但是我遇到了如下情况:
    dc(data chan)只会送出一个数据,而且那个数据(也就是文件名),在磁盘上是不存在的,那么对如如下代码

forloop:
	for {
		select {
		case vid := <-dc:
			go func(id interface{}) {
				if err := deleteVideo(id.(string)); err != nil {
					errMap.Store(id, err)
					return
				}
				if err := dbops.DelVideoDeletionRecord(id.(string)); err != nil {
					errMap.Store(id, err)
					return
				}
			}(vid)
		default:
			break forloop
		}
	}

case vid :=<- dc 启动一个goroutine后就会立刻完成一次循环到default,然后break掉,这样子就结束了for循环,但是此时那个goroutine中的逻辑还没执行完,也就那个goroutine中出现的所有错误都无法捕获了,所以errMap 此时是空的,也就是返回了 nil ,然后在 startDispatch() 那个for循环中的那段代码

if err := r.Executor(r.Data); err != nil {
	r.Error <- CLOSE
} else {
	r.Controller <- READY_TO_DISPATCH
}

就会执行 r.Controller <- READY_TO_DISPATCH,然后再启动一个VideoClearExecutor ,再次从数据库中读取那个在磁盘中不存在的文件名,这就导致了一个goroutine的死循环,然后每隔一段时间就会生成一个这样的死循环;我觉得这个问题是很严重的,必须进行同步

写回答

2回答

Quincy515

2019-09-26

请问,你是如何枷锁实现同步的?

0
0

慕尼黑9152544

2019-05-10

没事的 啊 不用都行的啊

0
0

Go语言实战流媒体视频网站,高效学习Go高性能开发

从零开始,全面掌握Go语言编码的架构风格和开发Web的关键技能

996 学习 · 268 问题

查看课程