mirror of https://github.com/scrapy/scrapy.git
Add ExecutionEngine.close() method
This commit is contained in:
parent
dd9f777ba7
commit
8307c1212f
|
|
@ -84,6 +84,21 @@ class ExecutionEngine(object):
|
|||
dfd = self._close_all_spiders()
|
||||
return dfd.addBoth(lambda _: self._finish_stopping_engine())
|
||||
|
||||
def close(self):
|
||||
"""Close the execution engine gracefully.
|
||||
|
||||
If it has already been started, stop it. In all cases, close all spiders
|
||||
and the downloader.
|
||||
"""
|
||||
if self.running:
|
||||
# Will also close spiders and downloader
|
||||
return self.stop()
|
||||
elif self.open_spiders:
|
||||
# Will also close downloader
|
||||
return self._close_all_spiders()
|
||||
else:
|
||||
return defer.succeed(self.downloader.close())
|
||||
|
||||
def pause(self):
|
||||
"""Pause the execution engine"""
|
||||
self.paused = True
|
||||
|
|
|
|||
|
|
@ -73,8 +73,11 @@ class Crawler(object):
|
|||
yield self.engine.open_spider(self.spider, start_requests)
|
||||
yield defer.maybeDeferred(self.engine.start)
|
||||
except Exception:
|
||||
exc = defer.fail()
|
||||
self.crawling = False
|
||||
raise
|
||||
if self.engine is not None:
|
||||
yield self.engine.close()
|
||||
yield exc
|
||||
|
||||
def _create_spider(self, *args, **kwargs):
|
||||
return self.spidercls.from_crawler(self, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -226,3 +226,24 @@ with multiples lines
|
|||
s = dict(est[0])
|
||||
self.assertEqual(s['engine.spider.name'], crawler.spider.name)
|
||||
self.assertEqual(s['len(engine.scraper.slot.active)'], 1)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_graceful_crawl_error_handling(self):
|
||||
"""
|
||||
Test whether errors happening anywhere in Crawler.crawl() are properly
|
||||
reported (and not somehow swallowed) after a graceful engine shutdown.
|
||||
The errors should not come from within Scrapy's core but from within
|
||||
spiders/middlewares/etc., e.g. raised in Spider.start_requests(),
|
||||
SpiderMiddleware.process_start_requests(), etc.
|
||||
"""
|
||||
|
||||
class TestError(Exception):
|
||||
pass
|
||||
|
||||
class FaultySpider(SimpleSpider):
|
||||
def start_requests(self):
|
||||
raise TestError
|
||||
|
||||
crawler = get_crawler(FaultySpider)
|
||||
yield self.assertFailure(crawler.crawl(), TestError)
|
||||
self.assertFalse(crawler.crawling)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from twisted.web import server, static, util
|
|||
from twisted.trial import unittest
|
||||
|
||||
from scrapy import signals
|
||||
from scrapy.core.engine import ExecutionEngine
|
||||
from scrapy.utils.test import get_crawler
|
||||
from pydispatch import dispatcher
|
||||
from tests import tests_datadir
|
||||
|
|
@ -234,6 +235,29 @@ class EngineTest(unittest.TestCase):
|
|||
self.assertEqual({'spider': self.run.spider, 'reason': 'finished'},
|
||||
self.run.signals_catched[signals.spider_closed])
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_close_downloader(self):
|
||||
e = ExecutionEngine(get_crawler(TestSpider), lambda: None)
|
||||
yield e.close()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_close_spiders_downloader(self):
|
||||
e = ExecutionEngine(get_crawler(TestSpider), lambda: None)
|
||||
yield e.open_spider(TestSpider(), [])
|
||||
self.assertEqual(len(e.open_spiders), 1)
|
||||
yield e.close()
|
||||
self.assertEqual(len(e.open_spiders), 0)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_close_engine_spiders_downloader(self):
|
||||
e = ExecutionEngine(get_crawler(TestSpider), lambda: None)
|
||||
yield e.open_spider(TestSpider(), [])
|
||||
e.start()
|
||||
self.assertTrue(e.running)
|
||||
yield e.close()
|
||||
self.assertFalse(e.running)
|
||||
self.assertEqual(len(e.open_spiders), 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'runserver':
|
||||
|
|
|
|||
Loading…
Reference in New Issue