twisted的task之cooperator和scrapy的parallel()函数
def handle_spider_output(self, result, request, response, spider):
if not result:
return defer_succeed(None)
it = iter_errback(result, self.handle_spider_error, request, response, spider)
dfd = parallel(it, self.concurrent_items,
self._process_spidermw_output, request, response, spider)
return dfd
def iter_errback(iterable, errback, *a, **kw):
"""Wraps an iterable calling an errback if an error is caught while
iterating it.
"""
it = iter(iterable)
while True:
try:
yield next(it)
except StopIteration:
break
except:
errback(failure.Failure(), *a, **kw)
包装一个iter,使其可以在迭代时出现异常时调用 错误处理函数。
def parallel(iterable, count, callable, *args, **named):
"""Execute a callable over the objects in the given iterable, in parallel,
using no more than ``count`` concurrent calls. Taken from: http://jcalderone.livejournal.com/24285.html
"""
coop = task.Cooperator()
work = (callable(elem, *args, **named) for elem in iterable)
return defer.DeferredList([coop.coiterate(work) for _ in range(count)])
并行处理函数,通过twisted的task来实现的。work是一个生成器,每次迭代时,使work前进一步。defer.DeferredList([coop.coiterate(work) for _ in range(count)])生成count个cooperatertask,定时调用work,直到迭代完成。由此可见,蜘蛛输出是一个deferredlist,一个defer在执行callback时,return是defer时,会停止执行callback,等待到结果执行callback时才能再次继续执行。这样实现了defer的串联执行,外层defer相当于总控制,callback返回defer相当于下层的分支。
def coiterate(self, iterator, doneDeferred=None):
"""
Add an iterator to the list of iterators this L{Cooperator} is
currently running. Equivalent to L{cooperate}, but returns a L{defer.Deferred} that will
be fired when the task is done. @param doneDeferred: If specified, this will be the Deferred used as
the completion deferred. It is suggested that you use the default,
which creates a new Deferred for you. @return: a Deferred that will fire when the iterator finishes.
"""
if doneDeferred is None:
doneDeferred = defer.Deferred()
CooperativeTask(iterator, self).whenDone().chainDeferred(doneDeferred)
return doneDeferred
cooperator什么时候调用start开始执行任务?其实在构造cooperator时started=True,所以CooperativeTask()时,会把task加入cooperator,同时调用cooperator的_reschedule()使其可以参与调度。
def _addTask(self, task):
"""
Add a L{CooperativeTask} object to this L{Cooperator}.
"""
if self._stopped:
self._tasks.append(task) # XXX silly, I know, but _completeWith
# does the inverse
task._completeWith(SchedulerStopped(), Failure(SchedulerStopped()))
else:
self._tasks.append(task)
self._reschedule()
def _tick(self):#每次调度时会遍历没有停止的任务,每个任务会执行onework。
"""
Run one scheduler tick.
"""
self._delayedCall = None
for taskObj in self._tasksWhileNotStopped():
taskObj._oneWorkUnit()
self._reschedule() _mustScheduleOnStart = False
def _reschedule(self):
if not self._started:
self._mustScheduleOnStart = True
return
if self._delayedCall is None and self._tasks:
self._delayedCall = self._scheduler(self._tick)延时call为定时调用tick函数。
EPSILON = 0.00000001
def _defaultScheduler(x):
from twisted.internet import reactor
return reactor.callLater(_EPSILON, x)
通过self._scheduler(self._tick)(_defaultScheduler(x))使twisted的reactor能不断调用tick函数。
twisted的task之cooperator和scrapy的parallel()函数的更多相关文章
- scrapy item处理----cooperator和parallel()函数
		
twisted的task之cooperator和scrapy的parallel()函数 本文是关于下载结果返回后调用item处理的过程实现研究. 从scrapy的结果处理说起 def handle_s ...
 - 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
		
[源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...
 - scrapy之parallel
		
Limiting Parallelism jcalderone May 22nd, 2006 This blog has moved! Read this post and its comments ...
 - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
		
Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...
 - scrapy yield 回调函数不执行解决方案
		
yield Request(url=parse.urljoin(response.url, p_url),callback=self.parse_detail) 回调函数不执行: 加上: dont_f ...
 - scrapy框架Request函数callback参数为什么是self.parse而不是self.parse( )
		
加括号是调用函数,不加括号是指的是函数地址,此处只需要传入函数的地址,等待程序到时调用即可
 - twisted task.cpperator
		
twisted task.cpperator 1. twisted task.cpperator 1.1. 简介-cooperator 官方文档: https://twistedmat ...
 - scrapy 源码解析 (三):启动流程源码分析(三) ExecutionEngine执行引擎
		
ExecutionEngine执行引擎 上一篇分析了CrawlerProcess和Crawler对象的建立过程,在最终调用CrawlerProcess.start()之前,会首先建立Execution ...
 - Scrapy 爬虫 使用指南 完全教程
		
scrapy note command 全局命令: startproject :在 project_name 文件夹下创建一个名为 project_name 的Scrapy项目. scrapy sta ...
 
随机推荐
- 2018-2019-2 20165313《网络对抗技术》Exp1  缓冲区溢出实验
			
实践涉及指令 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令.(机器码:90) JNE:条件转移指令, ...
 - RedHat7系列(Centos/Debian) FireWall 防火墙 设置
			
RedHat 7 系列之后 系统把默认的iptables 换成了 Firewall 所以我们要适应 这个新的防火墙管理 -------------------服务相关----------------- ...
 - 自定义事件——Event和CustomEvent
			
之前在学习自定义事件时,在MDN的Event.initEvent()页面顶端有写:该特性已从Web标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性. 作 ...
 - MGR实现分析 - 成员管理与故障恢复实现
			
MySQL Group Replication(MGR)框架让MySQL具备了自动主从切换和故障恢复能力,举single primary(单主)模式为例,primary作为主节点对外提供读写服务,是唯 ...
 - TypeScript 学习资料
			
TypeScript 学习资料: 学习资料 网址 TypeScript Handbook(中文版)(推荐) https://m.runoob.com/manual/gitbook/TypeScript ...
 - mysql 视图 安全性(  mysql 表能读,但是视图不能读问题 )
			
安全性: 有两个选项 Definer:定义者 , 定义者有什么权限 ,访问视图的人就有什么权限 Invoker: 调用者 ,根据调用这个视图的当前用户来决定 有什么权限 采坑: 项目中有个复杂查询. ...
 - 【Jmeter】Address already in use : connect &&Permission denied: connect 解决方案
			
Address already in use : connect 该问题的原因为: Windows 提供给 TCP/IP链接的端口为 1024-5000,并且要四分钟来循环回收他们.就导致我们在短 ...
 - 小程序 iphone X 吸底按钮适配
			
问题图: 解决方法: // app.js App({ isIphoneX() { let isIphoneX = false wx.getSystemInfo({ su ...
 - CSS控制文字显示一行,超出显示省略号
			
这几天在项目需求里面遇到了很多之前没做过的需求,也慢慢更加认识到了css的强大,是真的强大.以后会把自己技术调研的东西都写出来,哪怕只是一点点或者很小的点,重在学习. “CSS控制文字显示一行,超出显 ...
 - 踩坑rosbag --clock
			
将rosbag的数据feed给lego-loam,输出地图.另外写了一个滤波节点,订阅地图,进行滤波操作,再发布出来. 由于输入给lego-loam的数据来自于rosbag,所以需要rosbag提供时 ...