From 73a57b06f9d8c963b9be2bdb83122a004a4a8b0b Mon Sep 17 00:00:00 2001
From: Flavio Curella <flavio.curella@gmail.com>
Date: Tue, 20 May 2014 11:24:23 -0500
Subject: [PATCH] replaced occurrences of master/slave terminology with
 leader/follower

---
 docs/ref/settings.txt               |  6 +--
 docs/topics/cache.txt               | 18 ++++-----
 docs/topics/db/multi-db.txt         | 60 ++++++++++++++---------------
 docs/topics/testing/advanced.txt    | 36 ++++++++---------
 tests/migrations/test_operations.py |  2 +-
 tests/multiple_database/routers.py  |  2 +-
 tests/multiple_database/tests.py    | 38 +++++++++---------
 7 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 9a0dbd686d..7fa7aba642 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -649,10 +649,10 @@ Default: ``None``
 The alias of the database that this database should mirror during
 testing.
 
-This setting exists to allow for testing of master/slave
+This setting exists to allow for testing of leader/follower
 configurations of multiple databases. See the documentation on
-:ref:`testing master/slave configurations
-<topics-testing-masterslave>` for details.
+:ref:`testing leader/follower configurations
+<topics-testing-leaderfollower>` for details.
 
 .. setting:: TEST_NAME
 
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index a5f9b3451c..502b77fbf7 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -222,29 +222,29 @@ won't appear in the models cache, but the model details can be used
 for routing purposes.
 
 For example, the following router would direct all cache read
-operations to ``cache_slave``, and all write operations to
-``cache_master``. The cache table will only be synchronized onto
-``cache_master``::
+operations to ``cache_follower``, and all write operations to
+``cache_leader``. The cache table will only be synchronized onto
+``cache_leader``::
 
     class CacheRouter(object):
         """A router to control all database cache operations"""
 
         def db_for_read(self, model, **hints):
-            "All cache read operations go to the slave"
+            "All cache read operations go to the follower"
             if model._meta.app_label in ('django_cache',):
-                return 'cache_slave'
+                return 'cache_follower'
             return None
 
         def db_for_write(self, model, **hints):
-            "All cache write operations go to master"
+            "All cache write operations go to leader"
             if model._meta.app_label in ('django_cache',):
-                return 'cache_master'
+                return 'cache_leader'
             return None
 
         def allow_migrate(self, db, model):
-            "Only install the cache model on master"
+            "Only install the cache model on leader"
             if model._meta.app_label in ('django_cache',):
-                return db == 'cache_master'
+                return db == 'cache_leader'
             return None
 
 If you don't specify routing directions for the database cache model,
diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt
index 470fe1cadb..3dee075e76 100644
--- a/docs/topics/db/multi-db.txt
+++ b/docs/topics/db/multi-db.txt
@@ -197,17 +197,17 @@ Using routers
 
 Database routers are installed using the :setting:`DATABASE_ROUTERS`
 setting. This setting defines a list of class names, each specifying a
-router that should be used by the master router
+router that should be used by the leader router
 (``django.db.router``).
 
-The master router is used by Django's database operations to allocate
+The leader router is used by Django's database operations to allocate
 database usage. Whenever a query needs to know which database to use,
-it calls the master router, providing a model and a hint (if
+it calls the leader router, providing a model and a hint (if
 available). Django then tries each router in turn until a database
 suggestion can be found. If no suggestion can be found, it tries the
 current ``_state.db`` of the hint instance. If a hint instance wasn't
 provided, or the instance doesn't currently have database state, the
-master router will allocate the ``default`` database.
+leader router will allocate the ``default`` database.
 
 An example
 ----------
@@ -225,16 +225,16 @@ An example
     introduce referential integrity problems that Django can't
     currently handle.
 
-    The master/slave configuration described is also flawed -- it
+    The leader/follower configuration described is also flawed -- it
     doesn't provide any solution for handling replication lag (i.e.,
     query inconsistencies introduced because of the time taken for a
-    write to propagate to the slaves). It also doesn't consider the
+    write to propagate to the followers). It also doesn't consider the
     interaction of transactions with the database utilization strategy.
 
 So - what does this mean in practice? Let's consider another sample
 configuration. This one will have several databases: one for the
-``auth`` application, and all other apps using a master/slave setup
-with two read slaves. Here are the settings specifying these
+``auth`` application, and all other apps using a leader/follower setup
+with two read followers. Here are the settings specifying these
 databases::
 
     DATABASES = {
@@ -244,20 +244,20 @@ databases::
             'USER': 'mysql_user',
             'PASSWORD': 'swordfish',
         },
-        'master': {
-            'NAME': 'master',
+        'leader': {
+            'NAME': 'leader',
             'ENGINE': 'django.db.backends.mysql',
             'USER': 'mysql_user',
             'PASSWORD': 'spam',
         },
-        'slave1': {
-            'NAME': 'slave1',
+        'follower1': {
+            'NAME': 'follower1',
             'ENGINE': 'django.db.backends.mysql',
             'USER': 'mysql_user',
             'PASSWORD': 'eggs',
         },
-        'slave2': {
-            'NAME': 'slave2',
+        'follower2': {
+            'NAME': 'follower2',
             'ENGINE': 'django.db.backends.mysql',
             'USER': 'mysql_user',
             'PASSWORD': 'bacon',
@@ -309,30 +309,30 @@ send queries for the ``auth`` app to ``auth_db``::
             return None
 
 And we also want a router that sends all other apps to the
-master/slave configuration, and randomly chooses a slave to read
+leader/follower configuration, and randomly chooses a follower to read
 from::
 
     import random
 
-    class MasterSlaveRouter(object):
+    class LeaderFollowerRouter(object):
         def db_for_read(self, model, **hints):
             """
-            Reads go to a randomly-chosen slave.
+            Reads go to a randomly-chosen follower.
             """
-            return random.choice(['slave1', 'slave2'])
+            return random.choice(['follower1', 'follower2'])
 
         def db_for_write(self, model, **hints):
             """
-            Writes always go to master.
+            Writes always go to leader.
             """
-            return 'master'
+            return 'leader'
 
         def allow_relation(self, obj1, obj2, **hints):
             """
             Relations between objects are allowed if both objects are
-            in the master/slave pool.
+            in the leader/follower pool.
             """
-            db_list = ('master', 'slave1', 'slave2')
+            db_list = ('leader', 'follower1', 'follower2')
             if obj1._state.db in db_list and obj2._state.db in db_list:
                 return True
             return None
@@ -347,17 +347,17 @@ Finally, in the settings file, we add the following (substituting
 ``path.to.`` with the actual python path to the module(s) where the
 routers are defined)::
 
-    DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.MasterSlaveRouter']
+    DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.LeaderFollowerRouter']
 
 The order in which routers are processed is significant. Routers will
 be queried in the order the are listed in the
 :setting:`DATABASE_ROUTERS` setting . In this example, the
-``AuthRouter`` is processed before the ``MasterSlaveRouter``, and as a
+``AuthRouter`` is processed before the ``LeaderFollowerRouter``, and as a
 result, decisions concerning the models in ``auth`` are processed
 before any other decision is made. If the :setting:`DATABASE_ROUTERS`
 setting listed the two routers in the other order,
-``MasterSlaveRouter.allow_migrate()`` would be processed first. The
-catch-all nature of the MasterSlaveRouter implementation would mean
+``LeaderFollowerRouter.allow_migrate()`` would be processed first. The
+catch-all nature of the LeaderFollowerRouter implementation would mean
 that all models would be available on all databases.
 
 With this setup installed, lets run some Django code::
@@ -369,7 +369,7 @@ With this setup installed, lets run some Django code::
     >>> # This save will also be directed to 'auth_db'
     >>> fred.save()
 
-    >>> # These retrieval will be randomly allocated to a slave database
+    >>> # These retrieval will be randomly allocated to a follower database
     >>> dna = Person.objects.get(name='Douglas Adams')
 
     >>> # A new object has no database allocation when created
@@ -379,10 +379,10 @@ With this setup installed, lets run some Django code::
     >>> # the same database as the author object
     >>> mh.author = dna
 
-    >>> # This save will force the 'mh' instance onto the master database...
+    >>> # This save will force the 'mh' instance onto the leader database...
     >>> mh.save()
 
-    >>> # ... but if we re-retrieve the object, it will come back on a slave
+    >>> # ... but if we re-retrieve the object, it will come back on a follower
     >>> mh = Book.objects.get(title='Mostly Harmless')
 
 
@@ -690,7 +690,7 @@ In addition, some objects are automatically created just after
   database).
 
 For common setups with multiple databases, it isn't useful to have these
-objects in more than one database. Common setups include master / slave and
+objects in more than one database. Common setups include leader / follower and
 connecting to external databases. Therefore, it's recommended:
 
 - either to run :djadmin:`migrate` only for the default database;
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index 3439686210..de9c09b919 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -64,16 +64,16 @@ The following is a simple unit test using the request factory::
 Tests and multiple databases
 ============================
 
-.. _topics-testing-masterslave:
+.. _topics-testing-leaderfollower:
 
-Testing master/slave configurations
+Testing leader/follower configurations
 -----------------------------------
 
-If you're testing a multiple database configuration with master/slave
+If you're testing a multiple database configuration with leader/follower
 replication, this strategy of creating test databases poses a problem.
 When the test databases are created, there won't be any replication,
-and as a result, data created on the master won't be seen on the
-slave.
+and as a result, data created on the leader won't be seen on the
+follower.
 
 To compensate for this, Django allows you to define that a database is
 a *test mirror*. Consider the following (simplified) example database
@@ -83,34 +83,34 @@ configuration::
         'default': {
             'ENGINE': 'django.db.backends.mysql',
             'NAME': 'myproject',
-            'HOST': 'dbmaster',
+            'HOST': 'dbleader',
              # ... plus some other settings
         },
-        'slave': {
+        'follower': {
             'ENGINE': 'django.db.backends.mysql',
             'NAME': 'myproject',
-            'HOST': 'dbslave',
+            'HOST': 'dbfollower',
             'TEST_MIRROR': 'default'
             # ... plus some other settings
         }
     }
 
-In this setup, we have two database servers: ``dbmaster``, described
-by the database alias ``default``, and ``dbslave`` described by the
-alias ``slave``. As you might expect, ``dbslave`` has been configured
-by the database administrator as a read slave of ``dbmaster``, so in
-normal activity, any write to ``default`` will appear on ``slave``.
+In this setup, we have two database servers: ``dbleader``, described
+by the database alias ``default``, and ``dbfollower`` described by the
+alias ``follower``. As you might expect, ``dbfollower`` has been configured
+by the database administrator as a read follower of ``dbleader``, so in
+normal activity, any write to ``default`` will appear on ``follower``.
 
 If Django created two independent test databases, this would break any
-tests that expected replication to occur. However, the ``slave``
+tests that expected replication to occur. However, the ``follower``
 database has been configured as a test mirror (using the
 :setting:`TEST_MIRROR` setting), indicating that under testing,
-``slave`` should be treated as a mirror of ``default``.
+``follower`` should be treated as a mirror of ``default``.
 
-When the test environment is configured, a test version of ``slave``
-will *not* be created. Instead the connection to ``slave``
+When the test environment is configured, a test version of ``follower``
+will *not* be created. Instead the connection to ``follower``
 will be redirected to point at ``default``. As a result, writes to
-``default`` will appear on ``slave`` -- but because they are actually
+``default`` will appear on ``follower`` -- but because they are actually
 the same database, not because there is data replication between the
 two databases.
 
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index d294bdcd26..b16a6b9073 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -765,7 +765,7 @@ class MultiDBOperationTests(MigrationTestBase):
     multi_db = True
 
     def setUp(self):
-        # Make the 'other' database appear to be a slave of the 'default'
+        # Make the 'other' database appear to be a follower of the 'default'
         self.old_routers = router.routers
         router.routers = [MigrateNothingRouter()]
 
diff --git a/tests/multiple_database/routers.py b/tests/multiple_database/routers.py
index 8a84e0b3d2..23da8df199 100644
--- a/tests/multiple_database/routers.py
+++ b/tests/multiple_database/routers.py
@@ -4,7 +4,7 @@ from django.db import DEFAULT_DB_ALIAS
 
 
 class TestRouter(object):
-    # A test router. The behavior is vaguely master/slave, but the
+    # A test router. The behavior is vaguely leader/follower, but the
     # databases aren't assumed to propagate changes.
     def db_for_read(self, model, instance=None, **hints):
         if instance:
diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py
index 01c6e1ef15..2e8b902fea 100644
--- a/tests/multiple_database/tests.py
+++ b/tests/multiple_database/tests.py
@@ -854,7 +854,7 @@ class QueryTestCase(TestCase):
         self.assertEqual(book.editor._state.db, 'other')
 
     def test_subquery(self):
-        """Make sure as_sql works with subqueries and master/slave."""
+        """Make sure as_sql works with subqueries and leader/follower."""
         sub = Person.objects.using('other').filter(name='fff')
         qs = Book.objects.filter(editor__in=sub)
 
@@ -919,7 +919,7 @@ class RouterTestCase(TestCase):
     multi_db = True
 
     def setUp(self):
-        # Make the 'other' database appear to be a slave of the 'default'
+        # Make the 'other' database appear to be a follower of the 'default'
         self.old_routers = router.routers
         router.routers = [TestRouter()]
 
@@ -1071,7 +1071,7 @@ class RouterTestCase(TestCase):
         try:
             dive.editor = marty
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1089,7 +1089,7 @@ class RouterTestCase(TestCase):
         except Book.DoesNotExist:
             self.fail('Source database should have a copy of saved object')
 
-        # This isn't a real master-slave database, so restore the original from other
+        # This isn't a real leader-follower database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
@@ -1097,7 +1097,7 @@ class RouterTestCase(TestCase):
         try:
             marty.edited = [pro, dive]
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Assignment implies a save, so database assignments of original objects have changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1111,7 +1111,7 @@ class RouterTestCase(TestCase):
         except Book.DoesNotExist:
             self.fail('Source database should have a copy of saved object')
 
-        # This isn't a real master-slave database, so restore the original from other
+        # This isn't a real leader-follower database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
@@ -1119,7 +1119,7 @@ class RouterTestCase(TestCase):
         try:
             marty.edited.add(dive)
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Add implies a save, so database assignments of original objects have changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1133,7 +1133,7 @@ class RouterTestCase(TestCase):
         except Book.DoesNotExist:
             self.fail('Source database should have a copy of saved object')
 
-        # This isn't a real master-slave database, so restore the original from other
+        # This isn't a real leader-follower database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
 
         # If you assign a FK object when the base object hasn't
@@ -1196,7 +1196,7 @@ class RouterTestCase(TestCase):
         mark = Person.objects.using('default').create(pk=2, name="Mark Pilgrim")
 
         # Now save back onto the usual database.
-        # This simulates master/slave - the objects exist on both database,
+        # This simulates leader/follower - the objects exist on both database,
         # but the _state.db is as it is for all other tests.
         pro.save(using='default')
         marty.save(using='default')
@@ -1213,7 +1213,7 @@ class RouterTestCase(TestCase):
         try:
             marty.book_set = [pro, dive]
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1232,7 +1232,7 @@ class RouterTestCase(TestCase):
         try:
             marty.book_set.add(dive)
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1251,7 +1251,7 @@ class RouterTestCase(TestCase):
         try:
             dive.authors = [mark, marty]
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1273,7 +1273,7 @@ class RouterTestCase(TestCase):
         try:
             dive.authors.add(marty)
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1311,7 +1311,7 @@ class RouterTestCase(TestCase):
         try:
             bob.userprofile = alice_profile
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(alice._state.db, 'default')
@@ -1342,7 +1342,7 @@ class RouterTestCase(TestCase):
         try:
             review1.content_object = dive
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(pro._state.db, 'default')
@@ -1361,7 +1361,7 @@ class RouterTestCase(TestCase):
         except Book.DoesNotExist:
             self.fail('Source database should have a copy of saved object')
 
-        # This isn't a real master-slave database, so restore the original from other
+        # This isn't a real leader-follower database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
@@ -1369,7 +1369,7 @@ class RouterTestCase(TestCase):
         try:
             dive.reviews.add(review1)
         except ValueError:
-            self.fail("Assignment across master/slave databases with a common source should be ok")
+            self.fail("Assignment across leader/follower databases with a common source should be ok")
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(pro._state.db, 'default')
@@ -1444,7 +1444,7 @@ class RouterTestCase(TestCase):
         self.assertEqual(pro.reviews.db_manager('default').all().db, 'default')
 
     def test_subquery(self):
-        """Make sure as_sql works with subqueries and master/slave."""
+        """Make sure as_sql works with subqueries and leader/follower."""
         # Create a book and author on the other database
 
         mark = Person.objects.using('other').create(name="Mark Pilgrim")
@@ -1482,7 +1482,7 @@ class AuthTestCase(TestCase):
     multi_db = True
 
     def setUp(self):
-        # Make the 'other' database appear to be a slave of the 'default'
+        # Make the 'other' database appear to be a follower of the 'default'
         self.old_routers = router.routers
         router.routers = [AuthRouter()]