Repository: scrapy/scrapy

Issue:
Make asyncio reactor a default
Should we make 'twisted.internet.asyncioreactor.AsyncioSelectorReactor' a default? If so, should it be default in Scrapy 2.7, or is it too soon? We can start with making it default in the project template; it looks safe enough for Scrapy 2.7, or is it?

The reactor was introduced in Scrapy 2.0; I don't recall any particular issues reported about it. It'd be good to have it as a default eventually, because there are more an more Scrapy plugins which rely on asyncio libraries.

Discussion:

Patch:
diff --git a/docs/topics/settings.rst b/docs/topics/settings.rst
index a711fd197..0b1ef71cf 100644
--- a/docs/topics/settings.rst
+++ b/docs/topics/settings.rst
@@ -1642,6 +1642,11 @@ install the default reactor defined by Twisted for the current platform. This
 is to maintain backward compatibility and avoid possible problems caused by
 using a non-default reactor.
 
+.. versionchanged:: VERSION
+   The :command:`startproject` command now sets this setting to
+   ``twisted.internet.asyncioreactor.AsyncioSelectorReactor`` in the generated
+   ``settings.py`` file.
+
 For additional information, see :doc:`core/howto/choosing-reactor`.
 
 
diff --git a/scrapy/templates/project/module/settings.py.tmpl b/scrapy/templates/project/module/settings.py.tmpl
index 5e541e2c0..c0c34e986 100644
--- a/scrapy/templates/project/module/settings.py.tmpl
+++ b/scrapy/templates/project/module/settings.py.tmpl
@@ -89,3 +89,4 @@ ROBOTSTXT_OBEY = True
 
 # Set settings whose default value is deprecated to a future-proof value
 REQUEST_FINGERPRINTER_IMPLEMENTATION = 'VERSION'
+TWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'


Test patch:
diff --git a/tests/test_commands.py b/tests/test_commands.py
index 76d5f3935..eaca41102 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -689,8 +689,15 @@ class MySpider(scrapy.Spider):
         ])
         self.assertIn("Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor", log)
 
-    def test_asyncio_enabled_false(self):
+    def test_asyncio_enabled_default(self):
         log = self.get_log(self.debug_log_spider, args=[])
+        self.assertIn("Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor", log)
+
+    def test_asyncio_enabled_false(self):
+        log = self.get_log(self.debug_log_spider, args=[
+            '-s', 'TWISTED_REACTOR=twisted.internet.selectreactor.SelectReactor'
+        ])
+        self.assertIn("Using reactor: twisted.internet.selectreactor.SelectReactor", log)
         self.assertNotIn("Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor", log)
 
     @mark.skipif(sys.implementation.name == 'pypy', reason='uvloop does not support pypy properly')