示例#1
0
// 添加请求到队列,并发安全
func (self *Matrix) Push(req *request.Request) {
	if sdl.checkStatus(status.STOP) {
		return
	}

	// 禁止并发,降低请求积存量
	self.Lock()
	defer self.Unlock()

	// 达到请求上限,停止该规则运行
	if self.maxPage >= 0 {
		return
	}

	// 暂停状态时等待,降低请求积存量
	waited := false
	for sdl.checkStatus(status.PAUSE) {
		waited = true
		runtime.Gosched()
	}
	if waited && sdl.checkStatus(status.STOP) {
		return
	}

	// 资源使用过多时等待,降低请求积存量
	waited = false
	for self.resCount > sdl.avgRes() {
		waited = true
		runtime.Gosched()
	}
	if waited && sdl.checkStatus(status.STOP) {
		return
	}

	// 不可重复下载的req
	if !req.IsReloadable() {
		hash := makeUnique(req)
		// 已存在成功记录时退出
		if self.hasHistory(hash) {
			return
		}
		// 添加到临时记录
		self.insertTempHistory(hash)
	}

	var priority = req.GetPriority()

	// 初始化该蜘蛛下该优先级队列
	if _, found := self.reqs[priority]; !found {
		self.priorities = append(self.priorities, priority)
		sort.Ints(self.priorities) // 从小到大排序
		self.reqs[priority] = []*request.Request{}
	}

	// 添加请求到队列
	self.reqs[priority] = append(self.reqs[priority], req)

	// 大致限制加入队列的请求量,并发情况下应该会比maxPage多
	atomic.AddInt64(&self.maxPage, 1)
}
示例#2
0
// 返回是否作为新的失败请求被添加至队列尾部
func (self *Matrix) DoHistory(req *request.Request, ok bool) bool {
	hash := makeUnique(req)

	if !req.IsReloadable() {
		self.tempHistoryLock.Lock()
		delete(self.tempHistory, hash)
		self.tempHistoryLock.Unlock()

		if ok {
			self.history.UpsertSuccess(hash)
			return false
		}
	}

	if ok {
		return false
	}

	self.failureLock.Lock()
	defer self.failureLock.Unlock()
	if _, ok := self.failures[hash]; !ok {
		// 首次失败时,在任务队列末尾重新执行一次
		self.failures[hash] = req
		logs.Log.Informational(" *     + 失败请求: [%v]\n", req.GetUrl())
		return true
	}
	// 失败两次后,加入历史失败记录
	self.history.UpsertFailure(req)
	return false
}