Merge ~cjwatson/launchpad:rename-slave-store into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: e7f8ce7f6fa1fbacf82a518ce805e4720d4fc63e
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:rename-slave-store
Merge into: launchpad:master
Diff against target: 1495 lines (+201/-197)
47 files modified
cronscripts/librarian-feed-swift.py (+3/-3)
cronscripts/translations-export-to-branch.py (+1/-1)
lib/lp/app/stories/basics/xx-dbpolicy.txt (+32/-29)
lib/lp/bugs/scripts/bugtasktargetnamecaches.py (+2/-2)
lib/lp/buildmaster/model/builder.py (+2/-2)
lib/lp/code/model/branchcloud.py (+3/-3)
lib/lp/code/model/tests/test_branchcloud.py (+3/-2)
lib/lp/registry/scripts/teamparticipation.py (+3/-3)
lib/lp/services/database/doc/db-policy.txt (+2/-2)
lib/lp/services/database/doc/storm-store-reset.txt (+1/-1)
lib/lp/services/database/doc/storm.txt (+17/-17)
lib/lp/services/database/interfaces.py (+2/-2)
lib/lp/services/database/policy.py (+2/-2)
lib/lp/services/database/tests/test_bulk.py (+9/-9)
lib/lp/services/database/transaction_policy.py (+2/-2)
lib/lp/services/librarian/tests/test_client.py (+2/-2)
lib/lp/services/librarianserver/swift.py (+3/-3)
lib/lp/services/oauth/model.py (+1/-1)
lib/lp/services/session/adapters.py (+4/-4)
lib/lp/services/session/configure.zcml (+1/-1)
lib/lp/services/session/tests/test_session.py (+2/-2)
lib/lp/services/webapp/adapter.py (+3/-3)
lib/lp/services/webapp/batching.py (+2/-2)
lib/lp/services/webapp/database.zcml (+2/-2)
lib/lp/services/webapp/doc/test_adapter_permissions.txt (+1/-1)
lib/lp/services/webapp/publication.py (+1/-1)
lib/lp/services/webapp/tests/test_dbpolicy.py (+47/-47)
lib/lp/services/worlddata/model/language.py (+2/-2)
lib/lp/soyuz/model/archive.py (+2/-2)
lib/lp/soyuz/tests/test_archive.py (+1/-1)
lib/lp/testing/factory.py (+1/-1)
lib/lp/translations/doc/poexport-request.txt (+1/-1)
lib/lp/translations/doc/poexportqueue-replication-lag.txt (+2/-2)
lib/lp/translations/doc/potmsgset.txt (+1/-1)
lib/lp/translations/interfaces/poexportrequest.py (+1/-1)
lib/lp/translations/interfaces/potmsgset.py (+2/-2)
lib/lp/translations/model/poexportrequest.py (+7/-7)
lib/lp/translations/model/potmsgset.py (+1/-1)
lib/lp/translations/model/translationgroup.py (+3/-3)
lib/lp/translations/model/translationimportqueue.py (+5/-5)
lib/lp/translations/model/vpoexport.py (+1/-1)
lib/lp/translations/scripts/tests/test_translations_to_branch.py (+4/-4)
lib/lp/translations/scripts/translations_to_branch.py (+2/-2)
lib/lp/translations/tests/test_autoapproval.py (+2/-2)
lib/lp/translations/tests/test_translationimportqueue.py (+6/-6)
scripts/get-stacked-on-branches.py (+2/-2)
utilities/soyuz-sampledata-setup.py (+2/-2)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+414253@code.launchpad.net

Commit message

Rename ISlaveStore to IStandbyStore

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/cronscripts/librarian-feed-swift.py b/cronscripts/librarian-feed-swift.py
index ae60177..1cb1374 100755
--- a/cronscripts/librarian-feed-swift.py
+++ b/cronscripts/librarian-feed-swift.py
@@ -11,7 +11,7 @@ import os
1111
12import six12import six
1313
14from lp.services.database.interfaces import ISlaveStore14from lp.services.database.interfaces import IStandbyStore
15from lp.services.librarian.model import LibraryFileContent15from lp.services.librarian.model import LibraryFileContent
16from lp.services.librarianserver import swift16from lp.services.librarianserver import swift
17from lp.services.scripts.base import LaunchpadCronScript17from lp.services.scripts.base import LaunchpadCronScript
@@ -75,14 +75,14 @@ class LibrarianFeedSwift(LaunchpadCronScript):
75 remove = None75 remove = None
7676
77 if self.options.start_since:77 if self.options.start_since:
78 self.options.start = ISlaveStore(LibraryFileContent).execute("""78 self.options.start = IStandbyStore(LibraryFileContent).execute("""
79 SELECT MAX(id) FROM LibraryFileContent79 SELECT MAX(id) FROM LibraryFileContent
80 WHERE datecreated < current_timestamp at time zone 'UTC'80 WHERE datecreated < current_timestamp at time zone 'UTC'
81 - CAST(%s AS INTERVAL)81 - CAST(%s AS INTERVAL)
82 """, (six.text_type(self.options.start_since),)).get_one()[0]82 """, (six.text_type(self.options.start_since),)).get_one()[0]
8383
84 if self.options.end_at:84 if self.options.end_at:
85 self.options.end = ISlaveStore(LibraryFileContent).execute("""85 self.options.end = IStandbyStore(LibraryFileContent).execute("""
86 SELECT MAX(id) FROM LibraryFileContent86 SELECT MAX(id) FROM LibraryFileContent
87 WHERE datecreated < current_timestamp at time zone 'UTC'87 WHERE datecreated < current_timestamp at time zone 'UTC'
88 - CAST(%s AS INTERVAL)88 - CAST(%s AS INTERVAL)
diff --git a/cronscripts/translations-export-to-branch.py b/cronscripts/translations-export-to-branch.py
index 308c693..ca5d1dd 100755
--- a/cronscripts/translations-export-to-branch.py
+++ b/cronscripts/translations-export-to-branch.py
@@ -10,7 +10,7 @@ access hosted branches.
1010
11Besides committing to branches, the script updates Branch records in the11Besides committing to branches, the script updates Branch records in the
12database, to let the branch scanner know that the branches' contents12database, to let the branch scanner know that the branches' contents
13have been updated. For the rest, the script talks to the slave store.13have been updated. For the rest, the script talks to the standby store.
14"""14"""
1515
16__all__ = []16__all__ = []
diff --git a/lib/lp/app/stories/basics/xx-dbpolicy.txt b/lib/lp/app/stories/basics/xx-dbpolicy.txt
index b0b8e21..c4ffa89 100644
--- a/lib/lp/app/stories/basics/xx-dbpolicy.txt
+++ b/lib/lp/app/stories/basics/xx-dbpolicy.txt
@@ -4,11 +4,11 @@ Application Server Database Policy
4The database policy chooses the default Storm store to used. Its goal4The database policy chooses the default Storm store to used. Its goal
5is to distribute load away from the master databases to read only5is to distribute load away from the master databases to read only
6stores where possible. It will benefit old code - new code should6stores where possible. It will benefit old code - new code should
7explicitly select objects from the master or slave stores as needed.7explicitly select objects from the master or standby stores as needed.
88
9To test this policy, lets point the MAIN SLAVE store to a Launchpad9To test this policy, lets point the MAIN STANDBY store to a Launchpad
10database with a different name. This makes it easy to check if a10database with a different name. This makes it easy to check if a
11request is querying the master or slave database.11request is querying the master or standby database.
1212
13 >>> from lp.services.config import config13 >>> from lp.services.config import config
14 >>> from textwrap import dedent14 >>> from textwrap import dedent
@@ -19,21 +19,24 @@ request is querying the master or slave database.
19 >>> config.push('empty_standby', config_overlay)19 >>> config.push('empty_standby', config_overlay)
2020
21 >>> from lp.registry.model.person import Person21 >>> from lp.registry.model.person import Person
22 >>> from lp.services.database.interfaces import IMasterStore, ISlaveStore22 >>> from lp.services.database.interfaces import (
23 ... IMasterStore,
24 ... IStandbyStore,
25 ... )
23 >>> from lp.testing.layers import DatabaseLayer26 >>> from lp.testing.layers import DatabaseLayer
24 >>> master = IMasterStore(Person)27 >>> master = IMasterStore(Person)
25 >>> dbname = DatabaseLayer._db_fixture.dbname28 >>> dbname = DatabaseLayer._db_fixture.dbname
26 >>> dbname == master.execute("SELECT current_database()").get_one()[0]29 >>> dbname == master.execute("SELECT current_database()").get_one()[0]
27 True30 True
28 >>> slave = ISlaveStore(Person)31 >>> standby = IStandbyStore(Person)
29 >>> print(slave.execute("SELECT current_database()").get_one()[0])32 >>> print(standby.execute("SELECT current_database()").get_one()[0])
30 launchpad_empty33 launchpad_empty
3134
32We should confirm that the empty database is as empty as we hope it is.35We should confirm that the empty database is as empty as we hope it is.
3336
34 >>> slave_store = ISlaveStore(Person)37 >>> standby_store = IStandbyStore(Person)
35 >>> master_store = IMasterStore(Person)38 >>> master_store = IMasterStore(Person)
36 >>> slave_store.find(Person).is_empty()39 >>> standby_store.find(Person).is_empty()
37 True40 True
38 >>> master_store.find(Person).is_empty()41 >>> master_store.find(Person).is_empty()
39 False42 False
@@ -46,16 +49,16 @@ needs to be created externally to this pagetest).
46 ... if dbname == DatabaseLayer._db_fixture.dbname:49 ... if dbname == DatabaseLayer._db_fixture.dbname:
47 ... return 'MASTER'50 ... return 'MASTER'
48 ... elif dbname == 'launchpad_empty':51 ... elif dbname == 'launchpad_empty':
49 ... return 'SLAVE'52 ... return 'STANDBY'
50 ... else:53 ... else:
51 ... return 'UNKNOWN'54 ... return 'UNKNOWN'
5255
53Read only requests such as GET and HEAD will use the MAIN SLAVE56Read only requests such as GET and HEAD will use the MAIN STANDBY
54Store by default.57Store by default.
5558
56 >>> browser.open('http://launchpad.test/+whichdb')59 >>> browser.open('http://launchpad.test/+whichdb')
57 >>> print(whichdb(browser))60 >>> print(whichdb(browser))
58 SLAVE61 STANDBY
5962
60POST requests might make updates, so they use the MAIN MASTER63POST requests might make updates, so they use the MAIN MASTER
61Store by default.64Store by default.
@@ -66,18 +69,18 @@ Store by default.
6669
67This is an unauthenticated browser. These typically have no session, unless70This is an unauthenticated browser. These typically have no session, unless
68special dispensation has been made. Without a session, subsequent requests71special dispensation has been made. Without a session, subsequent requests
69will then immediately return to using the SLAVE.72will then immediately return to using the STANDBY.
7073
71 >>> browser.open('http://launchpad.test/+whichdb')74 >>> browser.open('http://launchpad.test/+whichdb')
72 >>> print(whichdb(browser))75 >>> print(whichdb(browser))
73 SLAVE76 STANDBY
7477
75However, if the request has a session (that is, is authenticated; or is78However, if the request has a session (that is, is authenticated; or is
76unauthenticated, but under special dispensation to have a session), once a79unauthenticated, but under special dispensation to have a session), once a
77POST request has been made, further GET and HEAD requests from the same client80POST request has been made, further GET and HEAD requests from the same client
78continue to use the MAIN MASTER Store by default for 5 minutes. This ensures81continue to use the MAIN MASTER Store by default for 5 minutes. This ensures
79that a user will see any changes they have made immediately, even though the82that a user will see any changes they have made immediately, even though the
80slave databases may lag some time behind the master database.83standby databases may lag some time behind the master database.
8184
82 >>> browser.addHeader('Authorization', 'Basic mark@example.com:test')85 >>> browser.addHeader('Authorization', 'Basic mark@example.com:test')
83 >>> browser.getControl('Do Post').click() # POST request86 >>> browser.getControl('Do Post').click() # POST request
@@ -88,19 +91,19 @@ slave databases may lag some time behind the master database.
88 MASTER91 MASTER
8992
90GET and HEAD requests from other clients are unaffected though93GET and HEAD requests from other clients are unaffected though
91and use the MAIN SLAVE Store by default.94and use the MAIN STANDBY Store by default.
9295
93 >>> anon_browser.open('http://launchpad.test/+whichdb')96 >>> anon_browser.open('http://launchpad.test/+whichdb')
94 >>> print(whichdb(anon_browser))97 >>> print(whichdb(anon_browser))
95 SLAVE98 STANDBY
96 >>> admin_browser.open('http://launchpad.test/+whichdb')99 >>> admin_browser.open('http://launchpad.test/+whichdb')
97 >>> print(whichdb(admin_browser))100 >>> print(whichdb(admin_browser))
98 SLAVE101 STANDBY
99102
100If no more POST requests are made for 5 minutes, GET and HEAD103If no more POST requests are made for 5 minutes, GET and HEAD
101requests will once again be using the MAIN SLAVE store as we104requests will once again be using the MAIN STANDBY store as we
102can assume that any changes made to the master database have105can assume that any changes made to the master database have
103propagated to the slaves.106propagated to the standbys.
104107
105To test this, first we need to wind forward the database policy's clock.108To test this, first we need to wind forward the database policy's clock.
106109
@@ -119,18 +122,18 @@ To test this, first we need to wind forward the database policy's clock.
119122
120 >>> browser.open('http://launchpad.test/+whichdb')123 >>> browser.open('http://launchpad.test/+whichdb')
121 >>> print(whichdb(browser))124 >>> print(whichdb(browser))
122 SLAVE125 STANDBY
123126
124 >>> dbpolicy._now = _original_now # Reset the time machine.127 >>> dbpolicy._now = _original_now # Reset the time machine.
125128
126129
127When lag gets too bad, we stop using slave databases. This stops130When lag gets too bad, we stop using standby databases. This stops
128replication oddities from becoming too bad, as well as lightening the load131replication oddities from becoming too bad, as well as lightening the load
129on the slaves allowing them to catch up.132on the standbys allowing them to catch up.
130133
131 >>> anon_browser.open('http://launchpad.test/+whichdb')134 >>> anon_browser.open('http://launchpad.test/+whichdb')
132 >>> print(whichdb(anon_browser))135 >>> print(whichdb(anon_browser))
133 SLAVE136 STANDBY
134137
135 >>> dbpolicy._test_lag = timedelta(minutes=10)138 >>> dbpolicy._test_lag = timedelta(minutes=10)
136 >>> anon_browser.open('http://launchpad.test/+whichdb')139 >>> anon_browser.open('http://launchpad.test/+whichdb')
@@ -139,7 +142,7 @@ on the slaves allowing them to catch up.
139 >>> dbpolicy._test_lag = None142 >>> dbpolicy._test_lag = None
140143
141144
142A 404 error page is shown when code raises a LookupError. If a slave145A 404 error page is shown when code raises a LookupError. If a standby
143database is being used, this might have been caused by replication lag146database is being used, this might have been caused by replication lag
144if the missing data was only recently created. To fix this surprising147if the missing data was only recently created. To fix this surprising
145error, requests are always retried using the master database before148error, requests are always retried using the master database before
@@ -148,12 +151,12 @@ returning a 404 error to the user.
148 >>> anon_browser.handleErrors = True151 >>> anon_browser.handleErrors = True
149 >>> anon_browser.raiseHttpErrors = False152 >>> anon_browser.raiseHttpErrors = False
150153
151 # Confirm requests are going to the SLAVE154 # Confirm requests are going to the STANDBY
152 >>> anon_browser.open('http://launchpad.test/+whichdb')155 >>> anon_browser.open('http://launchpad.test/+whichdb')
153 >>> print(whichdb(anon_browser))156 >>> print(whichdb(anon_browser))
154 SLAVE157 STANDBY
155158
156 # The slave database contains no data, but we don't get159 # The standby database contains no data, but we don't get
157 # a 404 page - the request is retried against the MASTER.160 # a 404 page - the request is retried against the MASTER.
158 >>> anon_browser.open('http://launchpad.test/~stub')161 >>> anon_browser.open('http://launchpad.test/~stub')
159 >>> anon_browser.headers['Status']162 >>> anon_browser.headers['Status']
@@ -165,10 +168,10 @@ returning a 404 error to the user.
165 >>> anon_browser.headers['Status']168 >>> anon_browser.headers['Status']
166 '404 Not Found'169 '404 Not Found'
167170
168 # This session is still using the SLAVE though by default.171 # This session is still using the STANDBY though by default.
169 >>> anon_browser.open('http://launchpad.test/+whichdb')172 >>> anon_browser.open('http://launchpad.test/+whichdb')
170 >>> print(whichdb(anon_browser))173 >>> print(whichdb(anon_browser))
171 SLAVE174 STANDBY
172175
173Reset our config to avoid affecting other tests.176Reset our config to avoid affecting other tests.
174177
diff --git a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
index d6cc18d..3d741fc 100644
--- a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
+++ b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
@@ -21,7 +21,7 @@ from lp.registry.model.productseries import ProductSeries
21from lp.registry.model.sourcepackagename import SourcePackageName21from lp.registry.model.sourcepackagename import SourcePackageName
22from lp.services.database.interfaces import (22from lp.services.database.interfaces import (
23 IMasterStore,23 IMasterStore,
24 ISlaveStore,24 IStandbyStore,
25 )25 )
26from lp.services.looptuner import (26from lp.services.looptuner import (
27 ITunableLoop,27 ITunableLoop,
@@ -62,7 +62,7 @@ class BugTaskTargetNameCachesTunableLoop:
62 Returns a list of (target, set_of_cached_names) pairs, where target is62 Returns a list of (target, set_of_cached_names) pairs, where target is
63 a tuple of IDs from the columns in target_columns.63 a tuple of IDs from the columns in target_columns.
64 """64 """
65 store = ISlaveStore(BugTask)65 store = IStandbyStore(BugTask)
66 candidate_set = store.find(target_columns).config(distinct=True)66 candidate_set = store.find(target_columns).config(distinct=True)
67 candidates = defaultdict(set)67 candidates = defaultdict(set)
68 for candidate in candidate_set:68 for candidate in candidate_set:
diff --git a/lib/lp/buildmaster/model/builder.py b/lib/lp/buildmaster/model/builder.py
index eeef109..1fd92ec 100644
--- a/lib/lp/buildmaster/model/builder.py
+++ b/lib/lp/buildmaster/model/builder.py
@@ -50,7 +50,7 @@ from lp.services.database.constants import UTC_NOW
50from lp.services.database.decoratedresultset import DecoratedResultSet50from lp.services.database.decoratedresultset import DecoratedResultSet
51from lp.services.database.enumcol import DBEnum51from lp.services.database.enumcol import DBEnum
52from lp.services.database.interfaces import (52from lp.services.database.interfaces import (
53 ISlaveStore,53 IStandbyStore,
54 IStore,54 IStore,
55 )55 )
56from lp.services.database.stormbase import StormBase56from lp.services.database.stormbase import StormBase
@@ -300,7 +300,7 @@ class BuilderSet:
300300
301 def getBuildQueueSizes(self):301 def getBuildQueueSizes(self):
302 """See `IBuilderSet`."""302 """See `IBuilderSet`."""
303 results = ISlaveStore(BuildQueue).find((303 results = IStandbyStore(BuildQueue).find((
304 Count(),304 Count(),
305 Sum(BuildQueue.estimated_duration),305 Sum(BuildQueue.estimated_duration),
306 Processor,306 Processor,
diff --git a/lib/lp/code/model/branchcloud.py b/lib/lp/code/model/branchcloud.py
index e6969f3..000a1ad 100644
--- a/lib/lp/code/model/branchcloud.py
+++ b/lib/lp/code/model/branchcloud.py
@@ -29,7 +29,7 @@ from zope.interface import provider
29from lp.code.interfaces.branch import IBranchCloud29from lp.code.interfaces.branch import IBranchCloud
30from lp.code.model.revision import RevisionCache30from lp.code.model.revision import RevisionCache
31from lp.registry.model.product import Product31from lp.registry.model.product import Product
32from lp.services.database.interfaces import ISlaveStore32from lp.services.database.interfaces import IStandbyStore
3333
3434
35@provider(IBranchCloud)35@provider(IBranchCloud)
@@ -44,8 +44,8 @@ class BranchCloud:
44 commits = Alias(Count(RevisionCache.revision_id))44 commits = Alias(Count(RevisionCache.revision_id))
45 epoch = datetime.now(pytz.UTC) - timedelta(days=30)45 epoch = datetime.now(pytz.UTC) - timedelta(days=30)
46 # It doesn't matter if this query is even a whole day out of date, so46 # It doesn't matter if this query is even a whole day out of date, so
47 # use the slave store.47 # use the standby store.
48 result = ISlaveStore(RevisionCache).find(48 result = IStandbyStore(RevisionCache).find(
49 (Product.name,49 (Product.name,
50 commits,50 commits,
51 Count(distinct_revision_author),51 Count(distinct_revision_author),
diff --git a/lib/lp/code/model/tests/test_branchcloud.py b/lib/lp/code/model/tests/test_branchcloud.py
index 4fb7143..2af246f 100644
--- a/lib/lp/code/model/tests/test_branchcloud.py
+++ b/lib/lp/code/model/tests/test_branchcloud.py
@@ -37,8 +37,9 @@ class TestBranchCloud(TestCaseWithFactory):
3737
38 def getProductsWithInfo(self, num_products=None):38 def getProductsWithInfo(self, num_products=None):
39 """Get product cloud information."""39 """Get product cloud information."""
40 # Since we use the slave store to get the information, we need to40 # Since we use the standby store to get the information, we need to
41 # commit the transaction to make the information visible to the slave.41 # commit the transaction to make the information visible to the
42 # standby.
42 transaction.commit()43 transaction.commit()
43 cloud_info = self._branch_cloud.getProductsWithInfo(num_products)44 cloud_info = self._branch_cloud.getProductsWithInfo(num_products)
4445
diff --git a/lib/lp/registry/scripts/teamparticipation.py b/lib/lp/registry/scripts/teamparticipation.py
index cfca76a..cb15dff 100644
--- a/lib/lp/registry/scripts/teamparticipation.py
+++ b/lib/lp/registry/scripts/teamparticipation.py
@@ -30,7 +30,7 @@ from lp.registry.interfaces.teammembership import ACTIVE_STATES
30from lp.registry.model.teammembership import TeamParticipation30from lp.registry.model.teammembership import TeamParticipation
31from lp.services.database.interfaces import (31from lp.services.database.interfaces import (
32 IMasterStore,32 IMasterStore,
33 ISlaveStore,33 IStandbyStore,
34 )34 )
35from lp.services.database.sqlbase import (35from lp.services.database.sqlbase import (
36 quote,36 quote,
@@ -52,7 +52,7 @@ def check_teamparticipation_circular(log):
52 AND tp.person = tp2.team52 AND tp.person = tp2.team
53 AND tp.id != tp2.id;53 AND tp.id != tp2.id;
54 """54 """
55 circular_references = list(ISlaveStore(TeamParticipation).execute(query))55 circular_references = list(IStandbyStore(TeamParticipation).execute(query))
56 if len(circular_references) > 0:56 if len(circular_references) > 0:
57 raise LaunchpadScriptFailure(57 raise LaunchpadScriptFailure(
58 "Circular references found: %s" % circular_references)58 "Circular references found: %s" % circular_references)
@@ -93,7 +93,7 @@ def execute_long_query(store, log, interval, query):
93def fetch_team_participation_info(log):93def fetch_team_participation_info(log):
94 """Fetch people, teams, memberships and participations."""94 """Fetch people, teams, memberships and participations."""
95 slurp = partial(95 slurp = partial(
96 execute_long_query, ISlaveStore(TeamParticipation), log, 10000)96 execute_long_query, IStandbyStore(TeamParticipation), log, 10000)
9797
98 people = dict(98 people = dict(
99 slurp(99 slurp(
diff --git a/lib/lp/services/database/doc/db-policy.txt b/lib/lp/services/database/doc/db-policy.txt
index 8a1cce2..fbb9aae 100644
--- a/lib/lp/services/database/doc/db-policy.txt
+++ b/lib/lp/services/database/doc/db-policy.txt
@@ -31,8 +31,8 @@ of the primary, the better the overall performance of Launchpad will be.
31We can distribute this load over many standby databases but are limited to31We can distribute this load over many standby databases but are limited to
32a single primary.32a single primary.
3333
34 >>> from lp.services.database.interfaces import ISlaveStore34 >>> from lp.services.database.interfaces import IStandbyStore
35 >>> ro_janitor = ISlaveStore(Person).find(35 >>> ro_janitor = IStandbyStore(Person).find(
36 ... Person, Person.name == 'janitor').one()36 ... Person, Person.name == 'janitor').one()
37 >>> ro_janitor is writable_janitor37 >>> ro_janitor is writable_janitor
38 False38 False
diff --git a/lib/lp/services/database/doc/storm-store-reset.txt b/lib/lp/services/database/doc/storm-store-reset.txt
index 8380370..b22a9a6 100644
--- a/lib/lp/services/database/doc/storm-store-reset.txt
+++ b/lib/lp/services/database/doc/storm-store-reset.txt
@@ -28,7 +28,7 @@ we rely on that to find out whether or not to reset stores.
28 ... http = setupBrowser(auth="Basic foo.bar@canonical.com:test")28 ... http = setupBrowser(auth="Basic foo.bar@canonical.com:test")
29 ... http.open("http://launchpad.test/~salgado/+edit")29 ... http.open("http://launchpad.test/~salgado/+edit")
30 ... http.getControl("Display Name").value = "Changed"30 ... http.getControl("Display Name").value = "Changed"
31 ... # Need a POST or the DB policy will be using the slave.31 ... # Need a POST or the DB policy will be using the standby.
32 ... http.getControl("Save Changes").click()32 ... http.getControl("Save Changes").click()
33 ... alive_items = len(IStore(Person)._alive)33 ... alive_items = len(IStore(Person)._alive)
3434
diff --git a/lib/lp/services/database/doc/storm.txt b/lib/lp/services/database/doc/storm.txt
index 82823a5..2690d05 100644
--- a/lib/lp/services/database/doc/storm.txt
+++ b/lib/lp/services/database/doc/storm.txt
@@ -4,7 +4,7 @@ back into the main replication set as part of login server separation.
4-- StuartBishop 201002224-- StuartBishop 20100222
55
6In addition to what Storm provides, we also have some Launchpad6In addition to what Storm provides, we also have some Launchpad
7specific Storm tools to cope with our master and slave store arrangement.7specific Storm tools to cope with our master and standby store arrangement.
88
9 >>> from lp.services.identity.interfaces.emailaddress import (9 >>> from lp.services.identity.interfaces.emailaddress import (
10 ... EmailAddressStatus,10 ... EmailAddressStatus,
@@ -13,7 +13,7 @@ specific Storm tools to cope with our master and slave store arrangement.
13 >>> from lp.services.database.interfaces import (13 >>> from lp.services.database.interfaces import (
14 ... IMasterObject,14 ... IMasterObject,
15 ... IMasterStore,15 ... IMasterStore,
16 ... ISlaveStore,16 ... IStandbyStore,
17 ... IStore,17 ... IStore,
18 ... )18 ... )
19 >>> from lp.services.identity.model.emailaddress import EmailAddress19 >>> from lp.services.identity.model.emailaddress import EmailAddress
@@ -33,33 +33,33 @@ provides.
3333
34 >>> IMasterStore.providedBy(main_master)34 >>> IMasterStore.providedBy(main_master)
35 True35 True
36 >>> ISlaveStore.providedBy(main_master)36 >>> IStandbyStore.providedBy(main_master)
37 False37 False
3838
3939
40Changes to the slave Stores will lag behind the master Stores. If40Changes to the standby Stores will lag behind the master Stores. If
41you only need to read an object but require it to be in sync with the41you only need to read an object but require it to be in sync with the
42master, you should use the default Store. Launchpad will give you the42master, you should use the default Store. Launchpad will give you the
43slave store if it is sure all your recent changes have been replicated.43standby store if it is sure all your recent changes have been replicated.
44Otherwise, it gives you the master. See IStoreSelector for details.44Otherwise, it gives you the master. See IStoreSelector for details.
4545
46 >>> main_default = IStore(Person)46 >>> main_default = IStore(Person)
47 >>> main_slave = ISlaveStore(Person)47 >>> main_standby = IStandbyStore(Person)
48 >>> main_default is main_master48 >>> main_default is main_master
49 True49 True
50 >>> main_default is main_slave50 >>> main_default is main_standby
51 False51 False
5252
5353
54You can also adapt database object instances to Stores, although54You can also adapt database object instances to Stores, although
55this is less generally useful.55this is less generally useful.
5656
57 >>> janitor = ISlaveStore(Person).find(Person, name='janitor').one()57 >>> janitor = IStandbyStore(Person).find(Person, name='janitor').one()
58 >>> ISlaveStore(janitor) is ISlaveStore(Person)58 >>> IStandbyStore(janitor) is IStandbyStore(Person)
59 True59 True
60 >>> IMasterStore(janitor) is IMasterStore(Person)60 >>> IMasterStore(janitor) is IMasterStore(Person)
61 True61 True
62 >>> IMasterStore(janitor) is ISlaveStore(Person)62 >>> IMasterStore(janitor) is IStandbyStore(Person)
63 False63 False
6464
6565
@@ -68,9 +68,9 @@ Good defensive programming is to use this adapter if you want to make
68changes to an object, just in case you have been passed an instance68changes to an object, just in case you have been passed an instance
69from a store other than the correct Master.69from a store other than the correct Master.
7070
71 >>> main_slave = ISlaveStore(Person)71 >>> main_standby = IStandbyStore(Person)
72 >>> t = transaction.begin()72 >>> t = transaction.begin()
73 >>> person = main_slave.find(Person, name='mark').one()73 >>> person = main_standby.find(Person, name='mark').one()
74 >>> person.display_name = 'Cannot change'74 >>> person.display_name = 'Cannot change'
75 >>> transaction.commit()75 >>> transaction.commit()
76 Traceback (most recent call last):76 Traceback (most recent call last):
@@ -79,7 +79,7 @@ from a store other than the correct Master.
7979
80 >>> transaction.abort()80 >>> transaction.abort()
81 >>> t = transaction.begin()81 >>> t = transaction.begin()
82 >>> person = main_slave.find(Person, name='mark').one()82 >>> person = main_standby.find(Person, name='mark').one()
83 >>> IMasterObject(person).display_name = 'Can change'83 >>> IMasterObject(person).display_name = 'Can change'
84 >>> transaction.commit()84 >>> transaction.commit()
8585
@@ -121,14 +121,14 @@ stores.
121 >>> master_email = IMasterStore(EmailAddress).find(121 >>> master_email = IMasterStore(EmailAddress).find(
122 ... EmailAddress, Person.name == 'janitor',122 ... EmailAddress, Person.name == 'janitor',
123 ... EmailAddress.person==Person.id).one()123 ... EmailAddress.person==Person.id).one()
124 >>> slave_email = ISlaveStore(EmailAddress).find(124 >>> standby_email = IStandbyStore(EmailAddress).find(
125 ... EmailAddress, Person.name == 'janitor',125 ... EmailAddress, Person.name == 'janitor',
126 ... EmailAddress.person==Person.id).one()126 ... EmailAddress.person==Person.id).one()
127 >>> master_email is slave_email127 >>> master_email is standby_email
128 False128 False
129 >>> master_email == slave_email129 >>> master_email == standby_email
130 True130 True
131 >>> master_email != slave_email131 >>> master_email != standby_email
132 False132 False
133133
134Comparison works for security wrapped objects too.134Comparison works for security wrapped objects too.
diff --git a/lib/lp/services/database/interfaces.py b/lib/lp/services/database/interfaces.py
index 5e89515..aae6350 100644
--- a/lib/lp/services/database/interfaces.py
+++ b/lib/lp/services/database/interfaces.py
@@ -9,8 +9,8 @@ __all__ = [
9 'IMasterObject',9 'IMasterObject',
10 'IMasterStore',10 'IMasterStore',
11 'IRequestExpired',11 'IRequestExpired',
12 'ISlaveStore',
13 'ISQLBase',12 'ISQLBase',
13 'IStandbyStore',
14 'IStore',14 'IStore',
15 'IStoreSelector',15 'IStoreSelector',
16 'MAIN_STORE',16 'MAIN_STORE',
@@ -153,7 +153,7 @@ class IMasterStore(IStore):
153 """A writeable Storm Stores."""153 """A writeable Storm Stores."""
154154
155155
156class ISlaveStore(IStore):156class IStandbyStore(IStore):
157 """A read-only Storm Store."""157 """A read-only Storm Store."""
158158
159159
diff --git a/lib/lp/services/database/policy.py b/lib/lp/services/database/policy.py
index a50fe3d..8d8f4e3 100644
--- a/lib/lp/services/database/policy.py
+++ b/lib/lp/services/database/policy.py
@@ -44,7 +44,7 @@ from lp.services.database.interfaces import (
44 DisallowedStore,44 DisallowedStore,
45 IDatabasePolicy,45 IDatabasePolicy,
46 IMasterStore,46 IMasterStore,
47 ISlaveStore,47 IStandbyStore,
48 IStoreSelector,48 IStoreSelector,
49 MAIN_STORE,49 MAIN_STORE,
50 PRIMARY_FLAVOR,50 PRIMARY_FLAVOR,
@@ -158,7 +158,7 @@ class BaseDatabasePolicy:
158 if flavor == PRIMARY_FLAVOR:158 if flavor == PRIMARY_FLAVOR:
159 alsoProvides(store, IMasterStore)159 alsoProvides(store, IMasterStore)
160 else:160 else:
161 alsoProvides(store, ISlaveStore)161 alsoProvides(store, IStandbyStore)
162162
163 store._lp_store_initialized = True163 store._lp_store_initialized = True
164164
diff --git a/lib/lp/services/database/tests/test_bulk.py b/lib/lp/services/database/tests/test_bulk.py
index a90d11e..78981ae 100644
--- a/lib/lp/services/database/tests/test_bulk.py
+++ b/lib/lp/services/database/tests/test_bulk.py
@@ -30,7 +30,7 @@ from lp.registry.model.person import Person
30from lp.services.database import bulk30from lp.services.database import bulk
31from lp.services.database.interfaces import (31from lp.services.database.interfaces import (
32 IMasterStore,32 IMasterStore,
33 ISlaveStore,33 IStandbyStore,
34 IStore,34 IStore,
35 )35 )
36from lp.services.database.sqlbase import (36from lp.services.database.sqlbase import (
@@ -131,13 +131,13 @@ class TestLoaders(TestCaseWithFactory):
131 db_object = self.factory.makeComponent()131 db_object = self.factory.makeComponent()
132 db_object_type = bulk.get_type(db_object)132 db_object_type = bulk.get_type(db_object)
133 # Commit so the database object is available in both master133 # Commit so the database object is available in both master
134 # and slave stores.134 # and standby stores.
135 transaction.commit()135 transaction.commit()
136 # Use a list, since objects corresponding to the same DB row from136 # Use a list, since objects corresponding to the same DB row from
137 # different stores compare equal.137 # different stores compare equal.
138 db_objects = [138 db_objects = [
139 IMasterStore(db_object).get(db_object_type, db_object.id),139 IMasterStore(db_object).get(db_object_type, db_object.id),
140 ISlaveStore(db_object).get(db_object_type, db_object.id),140 IStandbyStore(db_object).get(db_object_type, db_object.id),
141 ]141 ]
142 db_object_ids = {id(obj) for obj in db_objects}142 db_object_ids = {id(obj) for obj in db_objects}
143 db_queries = list(bulk.gen_reload_queries(db_objects))143 db_queries = list(bulk.gen_reload_queries(db_objects))
@@ -234,7 +234,7 @@ class TestLoaders(TestCaseWithFactory):
234 # load() can use an alternative store.234 # load() can use an alternative store.
235 db_object = self.factory.makeComponent()235 db_object = self.factory.makeComponent()
236 # Commit so the database object is available in both master236 # Commit so the database object is available in both master
237 # and slave stores.237 # and standby stores.
238 transaction.commit()238 transaction.commit()
239 # Master store.239 # Master store.
240 master_store = IMasterStore(db_object)240 master_store = IMasterStore(db_object)
@@ -242,12 +242,12 @@ class TestLoaders(TestCaseWithFactory):
242 Component, [db_object.id], store=master_store)242 Component, [db_object.id], store=master_store)
243 self.assertEqual(243 self.assertEqual(
244 Store.of(db_object_from_master), master_store)244 Store.of(db_object_from_master), master_store)
245 # Slave store.245 # Standby store.
246 slave_store = ISlaveStore(db_object)246 standby_store = IStandbyStore(db_object)
247 [db_object_from_slave] = bulk.load(247 [db_object_from_standby] = bulk.load(
248 Component, [db_object.id], store=slave_store)248 Component, [db_object.id], store=standby_store)
249 self.assertEqual(249 self.assertEqual(
250 Store.of(db_object_from_slave), slave_store)250 Store.of(db_object_from_standby), standby_store)
251251
252 def test_load_related(self):252 def test_load_related(self):
253 owning_objects = [253 owning_objects = [
diff --git a/lib/lp/services/database/transaction_policy.py b/lib/lp/services/database/transaction_policy.py
index bb1b403..8766894 100644
--- a/lib/lp/services/database/transaction_policy.py
+++ b/lib/lp/services/database/transaction_policy.py
@@ -24,7 +24,7 @@ class DatabaseTransactionPolicy:
2424
25 # We want to be sure that inspect_data does not inadvertently25 # We want to be sure that inspect_data does not inadvertently
26 # make any changes in the database, but we can't run it on the26 # make any changes in the database, but we can't run it on the
27 # slave store because it doesn't tolerate replication lag.27 # standby store because it doesn't tolerate replication lag.
28 with DatabaseTransactionPolicy(read_only=True):28 with DatabaseTransactionPolicy(read_only=True):
29 inspect_data()29 inspect_data()
3030
@@ -69,7 +69,7 @@ class DatabaseTransactionPolicy:
69 writability of database transactions.69 writability of database transactions.
7070
71 :param store: The store to set policy on. Defaults to the main master71 :param store: The store to set policy on. Defaults to the main master
72 store. You don't want to use this on a slave store!72 store. You don't want to use this on a standby store!
73 :param read_only: Is this policy read-only?73 :param read_only: Is this policy read-only?
74 """74 """
75 self.read_only = read_only75 self.read_only = read_only
diff --git a/lib/lp/services/librarian/tests/test_client.py b/lib/lp/services/librarian/tests/test_client.py
index cb054a9..6bef538 100644
--- a/lib/lp/services/librarian/tests/test_client.py
+++ b/lib/lp/services/librarian/tests/test_client.py
@@ -25,7 +25,7 @@ import transaction
2525
26from lp.services.config import config26from lp.services.config import config
27from lp.services.daemons.tachandler import TacTestSetup27from lp.services.daemons.tachandler import TacTestSetup
28from lp.services.database.interfaces import ISlaveStore28from lp.services.database.interfaces import IStandbyStore
29from lp.services.database.policy import StandbyDatabasePolicy29from lp.services.database.policy import StandbyDatabasePolicy
30from lp.services.database.sqlbase import block_implicit_flushes30from lp.services.database.sqlbase import block_implicit_flushes
31from lp.services.librarian import client as client_module31from lp.services.librarian import client as client_module
@@ -299,7 +299,7 @@ class LibrarianClientTestCase(TestCase):
299 # standby store and try to add a file, verifying that the primary299 # standby store and try to add a file, verifying that the primary
300 # is used.300 # is used.
301 client = LibrarianClient()301 client = LibrarianClient()
302 ISlaveStore(LibraryFileAlias).close()302 IStandbyStore(LibraryFileAlias).close()
303 with StandbyDatabasePolicy():303 with StandbyDatabasePolicy():
304 alias_id = client.addFile(304 alias_id = client.addFile(
305 'sample.txt', 6, io.BytesIO(b'sample'), 'text/plain')305 'sample.txt', 6, io.BytesIO(b'sample'), 'text/plain')
diff --git a/lib/lp/services/librarianserver/swift.py b/lib/lp/services/librarianserver/swift.py
index 637110f..ddb3125 100644
--- a/lib/lp/services/librarianserver/swift.py
+++ b/lib/lp/services/librarianserver/swift.py
@@ -24,7 +24,7 @@ from six.moves.urllib.parse import quote
24from swiftclient import client as swiftclient24from swiftclient import client as swiftclient
2525
26from lp.services.config import config26from lp.services.config import config
27from lp.services.database.interfaces import ISlaveStore27from lp.services.database.interfaces import IStandbyStore
28from lp.services.librarian.model import LibraryFileContent28from lp.services.librarian.model import LibraryFileContent
2929
3030
@@ -143,7 +143,7 @@ def to_swift(log, start_lfc_id=None, end_lfc_id=None,
143143
144 log.debug('Found {} ({})'.format(lfc, filename))144 log.debug('Found {} ({})'.format(lfc, filename))
145145
146 if ISlaveStore(LibraryFileContent).get(146 if IStandbyStore(LibraryFileContent).get(
147 LibraryFileContent, lfc) is None:147 LibraryFileContent, lfc) is None:
148 log.info("{} exists on disk but not in the db".format(148 log.info("{} exists on disk but not in the db".format(
149 lfc))149 lfc))
@@ -205,7 +205,7 @@ def _put(log, swift_connection, lfc_id, container, obj_name, fs_path):
205 fs_size = os.path.getsize(fs_path)205 fs_size = os.path.getsize(fs_path)
206 fs_file = HashStream(open(fs_path, 'rb'))206 fs_file = HashStream(open(fs_path, 'rb'))
207207
208 db_md5_hash = ISlaveStore(LibraryFileContent).get(208 db_md5_hash = IStandbyStore(LibraryFileContent).get(
209 LibraryFileContent, lfc_id).md5209 LibraryFileContent, lfc_id).md5
210210
211 assert hasattr(fs_file, 'tell') and hasattr(fs_file, 'seek'), '''211 assert hasattr(fs_file, 'tell') and hasattr(fs_file, 'seek'), '''
diff --git a/lib/lp/services/oauth/model.py b/lib/lp/services/oauth/model.py
index 3b48de6..2c07b19 100644
--- a/lib/lp/services/oauth/model.py
+++ b/lib/lp/services/oauth/model.py
@@ -68,7 +68,7 @@ class OAuthBase:
68 """Return the correct store for this class.68 """Return the correct store for this class.
6969
70 We want all OAuth classes to be retrieved from the master flavour. If70 We want all OAuth classes to be retrieved from the master flavour. If
71 they are retrieved from the slave, there will be problems in the71 they are retrieved from the standby, there will be problems in the
72 authorization exchange, since it will be done across applications that72 authorization exchange, since it will be done across applications that
73 won't share the session cookies.73 won't share the session cookies.
74 """74 """
diff --git a/lib/lp/services/session/adapters.py b/lib/lp/services/session/adapters.py
index 1cc2767..e2bc15b 100644
--- a/lib/lp/services/session/adapters.py
+++ b/lib/lp/services/session/adapters.py
@@ -11,7 +11,7 @@ from zope.interface import implementer
1111
12from lp.services.database.interfaces import (12from lp.services.database.interfaces import (
13 IMasterStore,13 IMasterStore,
14 ISlaveStore,14 IStandbyStore,
15 IStore,15 IStore,
16 )16 )
17from lp.services.database.sqlbase import session_store17from lp.services.database.sqlbase import session_store
@@ -26,9 +26,9 @@ def session_master_store(cls):
2626
2727
28@adapter(IUseSessionStore)28@adapter(IUseSessionStore)
29@implementer(ISlaveStore)29@implementer(IStandbyStore)
30def session_slave_store(cls):30def session_standby_store(cls):
31 """Adapt a Session database object to an `ISlaveStore`."""31 """Adapt a Session database object to an `IStandbyStore`."""
32 return session_store()32 return session_store()
3333
3434
diff --git a/lib/lp/services/session/configure.zcml b/lib/lp/services/session/configure.zcml
index dea1cd8..8c3c399 100644
--- a/lib/lp/services/session/configure.zcml
+++ b/lib/lp/services/session/configure.zcml
@@ -7,6 +7,6 @@
7 xmlns:i18n="http://namespaces.zope.org/i18n"7 xmlns:i18n="http://namespaces.zope.org/i18n"
8 i18n_domain="launchpad">8 i18n_domain="launchpad">
9 <adapter factory=".adapters.session_master_store" />9 <adapter factory=".adapters.session_master_store" />
10 <adapter factory=".adapters.session_slave_store" />10 <adapter factory=".adapters.session_standby_store" />
11 <adapter factory=".adapters.session_default_store" />11 <adapter factory=".adapters.session_default_store" />
12</configure>12</configure>
diff --git a/lib/lp/services/session/tests/test_session.py b/lib/lp/services/session/tests/test_session.py
index 6f5c1c0..10cab73 100644
--- a/lib/lp/services/session/tests/test_session.py
+++ b/lib/lp/services/session/tests/test_session.py
@@ -5,7 +5,7 @@
55
6from lp.services.database.interfaces import (6from lp.services.database.interfaces import (
7 IMasterStore,7 IMasterStore,
8 ISlaveStore,8 IStandbyStore,
9 IStore,9 IStore,
10 )10 )
11from lp.services.session.model import (11from lp.services.session.model import (
@@ -20,7 +20,7 @@ class TestSessionModelAdapters(TestCase):
20 layer = DatabaseFunctionalLayer20 layer = DatabaseFunctionalLayer
2121
22 def test_adapters(self):22 def test_adapters(self):
23 for adapter in [IMasterStore, ISlaveStore, IStore]:23 for adapter in [IMasterStore, IStandbyStore, IStore]:
24 for cls in [SessionData, SessionPkgData]:24 for cls in [SessionData, SessionPkgData]:
25 for obj in [cls, cls()]:25 for obj in [cls, cls()]:
26 store = adapter(obj)26 store = adapter(obj)
diff --git a/lib/lp/services/webapp/adapter.py b/lib/lp/services/webapp/adapter.py
index 26b4b6d..da15bfa 100644
--- a/lib/lp/services/webapp/adapter.py
+++ b/lib/lp/services/webapp/adapter.py
@@ -750,7 +750,7 @@ class StoreSelector:
750750
751751
752# We want to be able to adapt a Storm class to an IStore, IMasterStore or752# We want to be able to adapt a Storm class to an IStore, IMasterStore or
753# ISlaveStore. Unfortunately, the component architecture provides no753# IStandbyStore. Unfortunately, the component architecture provides no
754# way for us to declare that a class, and all its subclasses, provides754# way for us to declare that a class, and all its subclasses, provides
755# a given interface. This means we need to use an global adapter.755# a given interface. This means we need to use an global adapter.
756756
@@ -768,8 +768,8 @@ def get_master_store(storm_class):
768 return get_store(storm_class, PRIMARY_FLAVOR)768 return get_store(storm_class, PRIMARY_FLAVOR)
769769
770770
771def get_slave_store(storm_class):771def get_standby_store(storm_class):
772 """Return the master Store for the given database class."""772 """Return the standby Store for the given database class."""
773 return get_store(storm_class, STANDBY_FLAVOR)773 return get_store(storm_class, STANDBY_FLAVOR)
774774
775775
diff --git a/lib/lp/services/webapp/batching.py b/lib/lp/services/webapp/batching.py
index 894e6a6..b4c3b2b 100644
--- a/lib/lp/services/webapp/batching.py
+++ b/lib/lp/services/webapp/batching.py
@@ -36,7 +36,7 @@ from zope.security.proxy import (
36from lp.app.browser.launchpad import iter_view_registrations36from lp.app.browser.launchpad import iter_view_registrations
37from lp.services.config import config37from lp.services.config import config
38from lp.services.database.decoratedresultset import DecoratedResultSet38from lp.services.database.decoratedresultset import DecoratedResultSet
39from lp.services.database.interfaces import ISlaveStore39from lp.services.database.interfaces import IStandbyStore
40from lp.services.database.sqlbase import (40from lp.services.database.sqlbase import (
41 convert_storm_clause_to_string,41 convert_storm_clause_to_string,
42 sqlvalues,42 sqlvalues,
@@ -621,7 +621,7 @@ class StormRangeFactory:
621 select = removeSecurityProxy(self.plain_resultset).get_select_expr(621 select = removeSecurityProxy(self.plain_resultset).get_select_expr(
622 *columns)622 *columns)
623 explain = 'EXPLAIN ' + convert_storm_clause_to_string(select)623 explain = 'EXPLAIN ' + convert_storm_clause_to_string(select)
624 result = ISlaveStore(LibraryFileAlias).execute(explain)624 result = IStandbyStore(LibraryFileAlias).execute(explain)
625 _rows_re = re.compile(r"rows=(\d+)\swidth=")625 _rows_re = re.compile(r"rows=(\d+)\swidth=")
626 first_line = result.get_one()[0]626 first_line = result.get_one()[0]
627 match = _rows_re.search(first_line)627 match = _rows_re.search(first_line)
diff --git a/lib/lp/services/webapp/database.zcml b/lib/lp/services/webapp/database.zcml
index 2d9fcd1..c283ee1 100644
--- a/lib/lp/services/webapp/database.zcml
+++ b/lib/lp/services/webapp/database.zcml
@@ -46,9 +46,9 @@
46 factory="lp.services.webapp.adapter.get_master_store"46 factory="lp.services.webapp.adapter.get_master_store"
47 />47 />
48 <adapter48 <adapter
49 provides="lp.services.database.interfaces.ISlaveStore"49 provides="lp.services.database.interfaces.IStandbyStore"
50 for="zope.interface.Interface"50 for="zope.interface.Interface"
51 factory="lp.services.webapp.adapter.get_slave_store"51 factory="lp.services.webapp.adapter.get_standby_store"
52 />52 />
53 <!-- Universal adapter needed here per Bug #591841.53 <!-- Universal adapter needed here per Bug #591841.
54 We have no way of specifying that all subclasses of54 We have no way of specifying that all subclasses of
diff --git a/lib/lp/services/webapp/doc/test_adapter_permissions.txt b/lib/lp/services/webapp/doc/test_adapter_permissions.txt
index 2ae057f..35d35e3 100644
--- a/lib/lp/services/webapp/doc/test_adapter_permissions.txt
+++ b/lib/lp/services/webapp/doc/test_adapter_permissions.txt
@@ -5,7 +5,7 @@ traversed to from a PRIMARY_FLAVOR store.
5Because our development environment is not replicated, we use database5Because our development environment is not replicated, we use database
6permissions to ensure that tables we should not be writing to cannot6permissions to ensure that tables we should not be writing to cannot
7be written to. The same permissions structure is also used on production,7be written to. The same permissions structure is also used on production,
8so the Slony-I triggers blocking writes to some tables will never8so the Slony-I triggers blocking writes to replicated tables will never
9actually be invoked.9actually be invoked.
1010
11 >>> from lp.registry.model.person import Person11 >>> from lp.registry.model.person import Person
diff --git a/lib/lp/services/webapp/publication.py b/lib/lp/services/webapp/publication.py
index 31079d6..80effc1 100644
--- a/lib/lp/services/webapp/publication.py
+++ b/lib/lp/services/webapp/publication.py
@@ -703,7 +703,7 @@ class LaunchpadBrowserPublication(
703 return False703 return False
704704
705 # If we get a LookupError and the default database being705 # If we get a LookupError and the default database being
706 # used is a replica, raise a Retry exception instead of706 # used is a standby, raise a Retry exception instead of
707 # returning the 404 error page. We do this in case the707 # returning the 404 error page. We do this in case the
708 # LookupError is caused by replication lag. Our database708 # LookupError is caused by replication lag. Our database
709 # policy forces the use of the primary database for retries.709 # policy forces the use of the primary database for retries.
diff --git a/lib/lp/services/webapp/tests/test_dbpolicy.py b/lib/lp/services/webapp/tests/test_dbpolicy.py
index 8855268..a2a8120 100644
--- a/lib/lp/services/webapp/tests/test_dbpolicy.py
+++ b/lib/lp/services/webapp/tests/test_dbpolicy.py
@@ -36,7 +36,7 @@ from lp.services.database.interfaces import (
36 DisallowedStore,36 DisallowedStore,
37 IDatabasePolicy,37 IDatabasePolicy,
38 IMasterStore,38 IMasterStore,
39 ISlaveStore,39 IStandbyStore,
40 IStoreSelector,40 IStoreSelector,
41 MAIN_STORE,41 MAIN_STORE,
42 PRIMARY_FLAVOR,42 PRIMARY_FLAVOR,
@@ -110,7 +110,7 @@ class StandbyDatabasePolicyTestCase(BaseDatabasePolicyTestCase):
110 for store in ALL_STORES:110 for store in ALL_STORES:
111 self.assertProvides(111 self.assertProvides(
112 getUtility(IStoreSelector).get(store, DEFAULT_FLAVOR),112 getUtility(IStoreSelector).get(store, DEFAULT_FLAVOR),
113 ISlaveStore)113 IStandbyStore)
114114
115 def test_primary_allowed(self):115 def test_primary_allowed(self):
116 for store in ALL_STORES:116 for store in ALL_STORES:
@@ -157,7 +157,7 @@ class PrimaryDatabasePolicyTestCase(BaseDatabasePolicyTestCase):
157 for store in ALL_STORES:157 for store in ALL_STORES:
158 self.assertProvides(158 self.assertProvides(
159 getUtility(IStoreSelector).get(store, STANDBY_FLAVOR),159 getUtility(IStoreSelector).get(store, STANDBY_FLAVOR),
160 ISlaveStore)160 IStandbyStore)
161161
162162
163class LaunchpadDatabasePolicyTestCase(StandbyDatabasePolicyTestCase):163class LaunchpadDatabasePolicyTestCase(StandbyDatabasePolicyTestCase):
@@ -268,56 +268,56 @@ class PrimaryFallbackTestCase(TestCase):
268 '''Confirm that this TestCase's test infrastructure works as needed.268 '''Confirm that this TestCase's test infrastructure works as needed.
269 '''269 '''
270 master_store = IMasterStore(Person)270 master_store = IMasterStore(Person)
271 slave_store = ISlaveStore(Person)271 standby_store = IStandbyStore(Person)
272272
273 # Both Stores work when pgbouncer is up.273 # Both Stores work when pgbouncer is up.
274 master_store.get(Person, 1)274 master_store.get(Person, 1)
275 slave_store.get(Person, 1)275 standby_store.get(Person, 1)
276276
277 # Slave Store breaks when pgbouncer is torn down. Master Store277 # Standby Store breaks when pgbouncer is torn down. Master Store
278 # is fine.278 # is fine.
279 self.pgbouncer_fixture.stop()279 self.pgbouncer_fixture.stop()
280 master_store.get(Person, 2)280 master_store.get(Person, 2)
281 self.assertRaises(DisconnectionError, slave_store.get, Person, 2)281 self.assertRaises(DisconnectionError, standby_store.get, Person, 2)
282282
283 def test_startup_with_no_standby(self):283 def test_startup_with_no_standby(self):
284 '''An attempt is made for the first time to connect to a standby.'''284 '''An attempt is made for the first time to connect to a standby.'''
285 self.pgbouncer_fixture.stop()285 self.pgbouncer_fixture.stop()
286286
287 master_store = IMasterStore(Person)287 master_store = IMasterStore(Person)
288 slave_store = ISlaveStore(Person)288 standby_store = IStandbyStore(Person)
289289
290 # The master and slave Stores are the same object.290 # The master and standby Stores are the same object.
291 self.assertIs(master_store, slave_store)291 self.assertIs(master_store, standby_store)
292292
293 def test_standby_shutdown_during_transaction(self):293 def test_standby_shutdown_during_transaction(self):
294 '''Standby is shutdown while running, but we can recover.'''294 '''Standby is shutdown while running, but we can recover.'''
295 master_store = IMasterStore(Person)295 master_store = IMasterStore(Person)
296 slave_store = ISlaveStore(Person)296 standby_store = IStandbyStore(Person)
297297
298 self.assertIsNot(master_store, slave_store)298 self.assertIsNot(master_store, standby_store)
299299
300 self.pgbouncer_fixture.stop()300 self.pgbouncer_fixture.stop()
301301
302 # The transaction fails if the slave store is used. Robust302 # The transaction fails if the standby store is used. Robust
303 # processes will handle this and retry (even if just means exit303 # processes will handle this and retry (even if just means exit
304 # and wait for the next scheduled invocation).304 # and wait for the next scheduled invocation).
305 self.assertRaises(DisconnectionError, slave_store.get, Person, 1)305 self.assertRaises(DisconnectionError, standby_store.get, Person, 1)
306306
307 transaction.abort()307 transaction.abort()
308308
309 # But in the next transaction, we get the master Store if we ask309 # But in the next transaction, we get the master Store if we ask
310 # for the slave Store so we can continue.310 # for the standby Store so we can continue.
311 master_store = IMasterStore(Person)311 master_store = IMasterStore(Person)
312 slave_store = ISlaveStore(Person)312 standby_store = IStandbyStore(Person)
313313
314 self.assertIs(master_store, slave_store)314 self.assertIs(master_store, standby_store)
315315
316 def test_standby_shutdown_between_transactions(self):316 def test_standby_shutdown_between_transactions(self):
317 '''Standby is shutdown in between transactions.'''317 '''Standby is shutdown in between transactions.'''
318 master_store = IMasterStore(Person)318 master_store = IMasterStore(Person)
319 slave_store = ISlaveStore(Person)319 standby_store = IStandbyStore(Person)
320 self.assertIsNot(master_store, slave_store)320 self.assertIsNot(master_store, standby_store)
321321
322 transaction.abort()322 transaction.abort()
323 self.pgbouncer_fixture.stop()323 self.pgbouncer_fixture.stop()
@@ -325,31 +325,31 @@ class PrimaryFallbackTestCase(TestCase):
325 # The process doesn't notice the standby going down, and things325 # The process doesn't notice the standby going down, and things
326 # will fail the next time the standby is used.326 # will fail the next time the standby is used.
327 master_store = IMasterStore(Person)327 master_store = IMasterStore(Person)
328 slave_store = ISlaveStore(Person)328 standby_store = IStandbyStore(Person)
329 self.assertIsNot(master_store, slave_store)329 self.assertIsNot(master_store, standby_store)
330 self.assertRaises(DisconnectionError, slave_store.get, Person, 1)330 self.assertRaises(DisconnectionError, standby_store.get, Person, 1)
331331
332 # But now it has been discovered the socket is no longer332 # But now it has been discovered the socket is no longer
333 # connected to anything, next transaction we get a master333 # connected to anything, next transaction we get a master
334 # Store when we ask for a slave.334 # Store when we ask for a standby.
335 master_store = IMasterStore(Person)335 master_store = IMasterStore(Person)
336 slave_store = ISlaveStore(Person)336 standby_store = IStandbyStore(Person)
337 self.assertIs(master_store, slave_store)337 self.assertIs(master_store, standby_store)
338338
339 def test_standby_reconnect_after_outage(self):339 def test_standby_reconnect_after_outage(self):
340 '''The standby is again used once it becomes available.'''340 '''The standby is again used once it becomes available.'''
341 self.pgbouncer_fixture.stop()341 self.pgbouncer_fixture.stop()
342342
343 master_store = IMasterStore(Person)343 master_store = IMasterStore(Person)
344 slave_store = ISlaveStore(Person)344 standby_store = IStandbyStore(Person)
345 self.assertIs(master_store, slave_store)345 self.assertIs(master_store, standby_store)
346346
347 self.pgbouncer_fixture.start()347 self.pgbouncer_fixture.start()
348 transaction.abort()348 transaction.abort()
349349
350 master_store = IMasterStore(Person)350 master_store = IMasterStore(Person)
351 slave_store = ISlaveStore(Person)351 standby_store = IStandbyStore(Person)
352 self.assertIsNot(master_store, slave_store)352 self.assertIsNot(master_store, standby_store)
353353
354354
355class TestFastDowntimeRollout(TestCase):355class TestFastDowntimeRollout(TestCase):
@@ -401,7 +401,7 @@ class TestFastDowntimeRollout(TestCase):
401 '''You can always access a working standby store during fast downtime.401 '''You can always access a working standby store during fast downtime.
402 '''402 '''
403 # Everything is running happily.403 # Everything is running happily.
404 store = ISlaveStore(Person)404 store = IStandbyStore(Person)
405 original_store = store405 original_store = store
406 self.assertTrue(self.store_is_working(store))406 self.assertTrue(self.store_is_working(store))
407 self.assertTrue(self.store_is_standby(store))407 self.assertTrue(self.store_is_standby(store))
@@ -437,9 +437,9 @@ class TestFastDowntimeRollout(TestCase):
437 # But if we handle that and retry, we can continue.437 # But if we handle that and retry, we can continue.
438 # Now the failed connection has been detected, the next Store438 # Now the failed connection has been detected, the next Store
439 # we are handed is a primary Store instead of a standby.439 # we are handed is a primary Store instead of a standby.
440 store = ISlaveStore(Person)440 store = IStandbyStore(Person)
441 self.assertTrue(self.store_is_primary(store))441 self.assertTrue(self.store_is_primary(store))
442 self.assertIsNot(ISlaveStore(Person), original_store)442 self.assertIsNot(IStandbyStore(Person), original_store)
443443
444 # But alas, it might not work the first transaction. If it has444 # But alas, it might not work the first transaction. If it has
445 # been earlier, its connection was killed by pgbouncer earlier445 # been earlier, its connection was killed by pgbouncer earlier
@@ -449,7 +449,7 @@ class TestFastDowntimeRollout(TestCase):
449449
450 # Next retry attempt, everything is fine using the primary450 # Next retry attempt, everything is fine using the primary
451 # connection, even though our code only asked for a standby.451 # connection, even though our code only asked for a standby.
452 store = ISlaveStore(Person)452 store = IStandbyStore(Person)
453 self.assertTrue(self.store_is_primary(store))453 self.assertTrue(self.store_is_primary(store))
454 self.assertTrue(self.store_is_working(store))454 self.assertTrue(self.store_is_working(store))
455455
@@ -464,7 +464,7 @@ class TestFastDowntimeRollout(TestCase):
464 self.pgbouncer_cur.execute('ENABLE %s' % self.standby_dbname)464 self.pgbouncer_cur.execute('ENABLE %s' % self.standby_dbname)
465465
466 # And next transaction, we are back to normal.466 # And next transaction, we are back to normal.
467 store = ISlaveStore(Person)467 store = IStandbyStore(Person)
468 self.assertTrue(self.store_is_working(store))468 self.assertTrue(self.store_is_working(store))
469 self.assertTrue(self.store_is_standby(store))469 self.assertTrue(self.store_is_standby(store))
470 self.assertIs(original_store, store)470 self.assertIs(original_store, store)
@@ -477,9 +477,9 @@ class TestFastDowntimeRollout(TestCase):
477 self.assertTrue(self.store_is_primary(master_store))477 self.assertTrue(self.store_is_primary(master_store))
478 self.assertTrue(self.store_is_working(master_store))478 self.assertTrue(self.store_is_working(master_store))
479479
480 slave_store = ISlaveStore(Person)480 standby_store = IStandbyStore(Person)
481 self.assertTrue(self.store_is_standby(slave_store))481 self.assertTrue(self.store_is_standby(standby_store))
482 self.assertTrue(self.store_is_working(slave_store))482 self.assertTrue(self.store_is_working(standby_store))
483483
484 # But fast downtime is about to happen.484 # But fast downtime is about to happen.
485485
@@ -492,7 +492,7 @@ class TestFastDowntimeRollout(TestCase):
492 self.pgbouncer_cur.execute('KILL %s' % self.primary_dbname)492 self.pgbouncer_cur.execute('KILL %s' % self.primary_dbname)
493493
494 # Of course, standby connections are unaffected.494 # Of course, standby connections are unaffected.
495 self.assertTrue(self.store_is_working(slave_store))495 self.assertTrue(self.store_is_working(standby_store))
496496
497 # But attempts to use a primary store will fail.497 # But attempts to use a primary store will fail.
498 self.assertFalse(self.store_is_working(master_store))498 self.assertFalse(self.store_is_working(master_store))
@@ -515,18 +515,18 @@ class TestFastDowntimeRollout(TestCase):
515515
516 # The next attempt at accessing the standby store will fail516 # The next attempt at accessing the standby store will fail
517 # with a DisconnectionError.517 # with a DisconnectionError.
518 slave_store = ISlaveStore(Person)518 standby_store = IStandbyStore(Person)
519 self.assertTrue(self.store_is_standby(slave_store))519 self.assertTrue(self.store_is_standby(standby_store))
520 self.assertRaises(520 self.assertRaises(
521 DisconnectionError, slave_store.execute, 'SELECT TRUE')521 DisconnectionError, standby_store.execute, 'SELECT TRUE')
522 transaction.abort()522 transaction.abort()
523523
524 # But if we handle that and retry, we can continue.524 # But if we handle that and retry, we can continue.
525 # Now the failed connection has been detected, the next Store525 # Now the failed connection has been detected, the next Store
526 # we are handed is a primary Store instead of a standby.526 # we are handed is a primary Store instead of a standby.
527 slave_store = ISlaveStore(Person)527 standby_store = IStandbyStore(Person)
528 self.assertTrue(self.store_is_primary(slave_store))528 self.assertTrue(self.store_is_primary(standby_store))
529 self.assertTrue(self.store_is_working(slave_store))529 self.assertTrue(self.store_is_working(standby_store))
530530
531 # Once replication has caught up, the standby is reenabled.531 # Once replication has caught up, the standby is reenabled.
532 self.pgbouncer_cur.execute('RESUME %s' % self.standby_dbname)532 self.pgbouncer_cur.execute('RESUME %s' % self.standby_dbname)
@@ -538,6 +538,6 @@ class TestFastDowntimeRollout(TestCase):
538 self.assertTrue(self.store_is_primary(master_store))538 self.assertTrue(self.store_is_primary(master_store))
539 self.assertTrue(self.store_is_working(master_store))539 self.assertTrue(self.store_is_working(master_store))
540540
541 slave_store = ISlaveStore(Person)541 standby_store = IStandbyStore(Person)
542 self.assertTrue(self.store_is_standby(slave_store))542 self.assertTrue(self.store_is_standby(standby_store))
543 self.assertTrue(self.store_is_working(slave_store))543 self.assertTrue(self.store_is_working(standby_store))
diff --git a/lib/lp/services/worlddata/model/language.py b/lib/lp/services/worlddata/model/language.py
index aaff902..d4af9d6 100644
--- a/lib/lp/services/worlddata/model/language.py
+++ b/lib/lp/services/worlddata/model/language.py
@@ -26,7 +26,7 @@ from lp.registry.model.karma import (
26from lp.services.database.decoratedresultset import DecoratedResultSet26from lp.services.database.decoratedresultset import DecoratedResultSet
27from lp.services.database.enumcol import DBEnum27from lp.services.database.enumcol import DBEnum
28from lp.services.database.interfaces import (28from lp.services.database.interfaces import (
29 ISlaveStore,29 IStandbyStore,
30 IStore,30 IStore,
31 )31 )
32from lp.services.database.sqlbase import SQLBase32from lp.services.database.sqlbase import SQLBase
@@ -292,7 +292,7 @@ class LanguageSet:
292 """See `ILanguageSet`."""292 """See `ILanguageSet`."""
293 if text:293 if text:
294 text = six.ensure_text(text).lower()294 text = six.ensure_text(text).lower()
295 results = ISlaveStore(Language).find(295 results = IStandbyStore(Language).find(
296 Language, Or(296 Language, Or(
297 Language.code.lower().contains_string(text),297 Language.code.lower().contains_string(text),
298 Language.englishname.lower().contains_string(298 Language.englishname.lower().contains_string(
diff --git a/lib/lp/soyuz/model/archive.py b/lib/lp/soyuz/model/archive.py
index b3c7798..59312ea 100644
--- a/lib/lp/soyuz/model/archive.py
+++ b/lib/lp/soyuz/model/archive.py
@@ -105,7 +105,7 @@ from lp.services.database.datetimecol import UtcDateTimeCol
105from lp.services.database.decoratedresultset import DecoratedResultSet105from lp.services.database.decoratedresultset import DecoratedResultSet
106from lp.services.database.enumcol import DBEnum106from lp.services.database.enumcol import DBEnum
107from lp.services.database.interfaces import (107from lp.services.database.interfaces import (
108 ISlaveStore,108 IStandbyStore,
109 IStore,109 IStore,
110 )110 )
111from lp.services.database.sqlbase import (111from lp.services.database.sqlbase import (
@@ -1097,7 +1097,7 @@ class Archive(SQLBase):
1097 Component.name.is_in(components))1097 Component.name.is_in(components))
1098 for (archive, not_used, pocket, components) in deps])1098 for (archive, not_used, pocket, components) in deps])
10991099
1100 return ISlaveStore(BinaryPackagePublishingHistory).find(1100 return IStandbyStore(BinaryPackagePublishingHistory).find(
1101 BinaryPackagePublishingHistory,1101 BinaryPackagePublishingHistory,
1102 BinaryPackageName.name == dep_name,1102 BinaryPackageName.name == dep_name,
1103 BinaryPackagePublishingHistory.binarypackagename ==1103 BinaryPackagePublishingHistory.binarypackagename ==
diff --git a/lib/lp/soyuz/tests/test_archive.py b/lib/lp/soyuz/tests/test_archive.py
index 9e7be9a..cbc40ac 100644
--- a/lib/lp/soyuz/tests/test_archive.py
+++ b/lib/lp/soyuz/tests/test_archive.py
@@ -1901,7 +1901,7 @@ class TestFindDepCandidates(TestCaseWithFactory):
1901 archive, and compares it to the given expected value.1901 archive, and compares it to the given expected value.
1902 The archive defaults to self.archive.1902 The archive defaults to self.archive.
19031903
1904 Also commits, since findDepCandidates uses the slave store.1904 Also commits, since findDepCandidates uses the standby store.
1905 """1905 """
1906 transaction.commit()1906 transaction.commit()
19071907
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 71265f7..1588aad 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -397,7 +397,7 @@ def default_master_store(func):
397397
398 In some cases, such as in the middle of a page test story,398 In some cases, such as in the middle of a page test story,
399 we might be calling factory methods with the default Store set399 we might be calling factory methods with the default Store set
400 to the slave which breaks stuff. For instance, if we set an account's400 to the standby which breaks stuff. For instance, if we set an account's
401 password that needs to happen on the master store and this is forced.401 password that needs to happen on the master store and this is forced.
402 However, if we then read it back the default Store has to be used.402 However, if we then read it back the default Store has to be used.
403 """403 """
diff --git a/lib/lp/translations/doc/poexport-request.txt b/lib/lp/translations/doc/poexport-request.txt
index ba2b666..18d685d 100644
--- a/lib/lp/translations/doc/poexport-request.txt
+++ b/lib/lp/translations/doc/poexport-request.txt
@@ -33,7 +33,7 @@ Our user requests the Catalan and Czech translations of a template.
3333
34Now we request that the queue be processed.34Now we request that the queue be processed.
3535
36(Commits are needed to make the test requests seep through to the slave36(Commits are needed to make the test requests seep through to the standby
37database).37database).
3838
39 >>> import transaction39 >>> import transaction
diff --git a/lib/lp/translations/doc/poexportqueue-replication-lag.txt b/lib/lp/translations/doc/poexportqueue-replication-lag.txt
index 409fb71..e737cfc 100644
--- a/lib/lp/translations/doc/poexportqueue-replication-lag.txt
+++ b/lib/lp/translations/doc/poexportqueue-replication-lag.txt
@@ -2,7 +2,7 @@ Replication Lag and the Export Queue
2====================================2====================================
33
4Due to replication lag it's possible for the export queue to see a4Due to replication lag it's possible for the export queue to see a
5request on the slave store that it actually just removed from the master5request on the standby store that it actually just removed from the master
6store.6store.
77
8We start our story with an empty export queue.8We start our story with an empty export queue.
@@ -71,7 +71,7 @@ were to ask again.
71 ja71 ja
7272
73The first request is removed from the master store after processing, but73The first request is removed from the master store after processing, but
74not yet from the slave store. (Since this test is all one session, we74not yet from the standby store. (Since this test is all one session, we
75can reproduce this by not committing the removal). The second request75can reproduce this by not committing the removal). The second request
76is still technically on the queue, but no longer "live."76is still technically on the queue, but no longer "live."
7777
diff --git a/lib/lp/translations/doc/potmsgset.txt b/lib/lp/translations/doc/potmsgset.txt
index a7a8d79..da86a39 100644
--- a/lib/lp/translations/doc/potmsgset.txt
+++ b/lib/lp/translations/doc/potmsgset.txt
@@ -4,7 +4,7 @@ POTMsgSet tests
4POTMsgSet represents messages to translate that a POTemplate file has.4POTMsgSet represents messages to translate that a POTemplate file has.
55
6In this test we'll be committing a lot to let changes replicate to the6In this test we'll be committing a lot to let changes replicate to the
7slave database.7standby database.
88
9 >>> import transaction9 >>> import transaction
1010
diff --git a/lib/lp/translations/interfaces/poexportrequest.py b/lib/lp/translations/interfaces/poexportrequest.py
index de4ad9b..2d0968b 100644
--- a/lib/lp/translations/interfaces/poexportrequest.py
+++ b/lib/lp/translations/interfaces/poexportrequest.py
@@ -47,7 +47,7 @@ class IPOExportRequestSet(Interface):
47 * The requested `TranslationFileFormat`.47 * The requested `TranslationFileFormat`.
48 * The list of request record ids making up this request.48 * The list of request record ids making up this request.
4949
50 The objects are all read-only objects from the slave store. The50 The objects are all read-only objects from the standby store. The
51 request ids list should be passed to `removeRequest` when51 request ids list should be passed to `removeRequest` when
52 processing of the request completes.52 processing of the request completes.
53 """53 """
diff --git a/lib/lp/translations/interfaces/potmsgset.py b/lib/lp/translations/interfaces/potmsgset.py
index 4af6b3d..3390f5f 100644
--- a/lib/lp/translations/interfaces/potmsgset.py
+++ b/lib/lp/translations/interfaces/potmsgset.py
@@ -172,7 +172,7 @@ class IPOTMsgSet(Interface):
172 `POTMsgSet` that are actually used (i.e. current or imported) in172 `POTMsgSet` that are actually used (i.e. current or imported) in
173 other templates.173 other templates.
174174
175 The suggestions are read-only; they come from the slave store.175 The suggestions are read-only; they come from the standby store.
176176
177 :param language: language we want translations for.177 :param language: language we want translations for.
178 """178 """
@@ -184,7 +184,7 @@ class IPOTMsgSet(Interface):
184 `POTMsgSet` that were entered in another context, but for the184 `POTMsgSet` that were entered in another context, but for the
185 same English text, and are not in actual use.185 same English text, and are not in actual use.
186186
187 The suggestions are read-only; they come from the slave store.187 The suggestions are read-only; they come from the standby store.
188188
189 :param language: language we want translations for.189 :param language: language we want translations for.
190 """190 """
diff --git a/lib/lp/translations/model/poexportrequest.py b/lib/lp/translations/model/poexportrequest.py
index dc9b7d9..c532086 100644
--- a/lib/lp/translations/model/poexportrequest.py
+++ b/lib/lp/translations/model/poexportrequest.py
@@ -20,7 +20,7 @@ from lp.services.database.constants import DEFAULT
20from lp.services.database.enumcol import DBEnum20from lp.services.database.enumcol import DBEnum
21from lp.services.database.interfaces import (21from lp.services.database.interfaces import (
22 IMasterStore,22 IMasterStore,
23 ISlaveStore,23 IStandbyStore,
24 IStore,24 IStore,
25 )25 )
26from lp.services.database.sqlbase import quote26from lp.services.database.sqlbase import quote
@@ -121,7 +121,7 @@ class POExportRequestSet:
121 """Return the oldest live request on the master store.121 """Return the oldest live request on the master store.
122122
123 Due to replication lag, the master store is always a little123 Due to replication lag, the master store is always a little
124 ahead of the slave store that exports come from.124 ahead of the standby store that exports come from.
125 """125 """
126 master_store = IMasterStore(POExportRequest)126 master_store = IMasterStore(POExportRequest)
127 sorted_by_id = master_store.find(POExportRequest).order_by(127 sorted_by_id = master_store.find(POExportRequest).order_by(
@@ -130,7 +130,7 @@ class POExportRequestSet:
130130
131 def _getHeadRequest(self):131 def _getHeadRequest(self):
132 """Return oldest request on the queue."""132 """Return oldest request on the queue."""
133 # Due to replication lag, it's possible that the slave store133 # Due to replication lag, it's possible that the standby store
134 # still has copies of requests that have already been completed134 # still has copies of requests that have already been completed
135 # and deleted from the master store. So first get the oldest135 # and deleted from the master store. So first get the oldest
136 # request that is "live," i.e. still present on the master136 # request that is "live," i.e. still present on the master
@@ -139,21 +139,21 @@ class POExportRequestSet:
139 if oldest_live is None:139 if oldest_live is None:
140 return None140 return None
141 else:141 else:
142 return ISlaveStore(POExportRequest).find(142 return IStandbyStore(POExportRequest).find(
143 POExportRequest,143 POExportRequest,
144 POExportRequest.id == oldest_live.id).one()144 POExportRequest.id == oldest_live.id).one()
145145
146 def getRequest(self):146 def getRequest(self):
147 """See `IPOExportRequestSet`."""147 """See `IPOExportRequestSet`."""
148 # Exports happen off the slave store. To ensure that export148 # Exports happen off the standby store. To ensure that export
149 # does not happen until requests have been replicated to the149 # does not happen until requests have been replicated to the
150 # slave, they are read primarily from the slave even though they150 # standby, they are read primarily from the standby even though they
151 # are deleted on the master afterwards.151 # are deleted on the master afterwards.
152 head = self._getHeadRequest()152 head = self._getHeadRequest()
153 if head is None:153 if head is None:
154 return None, None, None, None154 return None, None, None, None
155155
156 requests = ISlaveStore(POExportRequest).find(156 requests = IStandbyStore(POExportRequest).find(
157 POExportRequest,157 POExportRequest,
158 POExportRequest.person == head.person,158 POExportRequest.person == head.person,
159 POExportRequest.format == head.format,159 POExportRequest.format == head.format,
diff --git a/lib/lp/translations/model/potmsgset.py b/lib/lp/translations/model/potmsgset.py
index 9435564..49c4051 100644
--- a/lib/lp/translations/model/potmsgset.py
+++ b/lib/lp/translations/model/potmsgset.py
@@ -374,7 +374,7 @@ class POTMsgSet(SQLBase):
374 A message is used if it's either imported or current, and unused374 A message is used if it's either imported or current, and unused
375 otherwise.375 otherwise.
376376
377 Suggestions are read-only, so these objects come from the slave377 Suggestions are read-only, so these objects come from the standby
378 store.378 store.
379379
380 :param suggested_languages: Languages that suggestions should be found380 :param suggested_languages: Languages that suggestions should be found
diff --git a/lib/lp/translations/model/translationgroup.py b/lib/lp/translations/model/translationgroup.py
index ab39ddf..c274697 100644
--- a/lib/lp/translations/model/translationgroup.py
+++ b/lib/lp/translations/model/translationgroup.py
@@ -25,7 +25,7 @@ from lp.services.database.constants import DEFAULT
25from lp.services.database.datetimecol import UtcDateTimeCol25from lp.services.database.datetimecol import UtcDateTimeCol
26from lp.services.database.decoratedresultset import DecoratedResultSet26from lp.services.database.decoratedresultset import DecoratedResultSet
27from lp.services.database.interfaces import (27from lp.services.database.interfaces import (
28 ISlaveStore,28 IStandbyStore,
29 IStore,29 IStore,
30 )30 )
31from lp.services.database.sqlbase import SQLBase31from lp.services.database.sqlbase import SQLBase
@@ -219,7 +219,7 @@ class TranslationGroup(SQLBase):
219 LibraryFileAlias,219 LibraryFileAlias,
220 LibraryFileContent,220 LibraryFileContent,
221 )221 )
222 project_data = ISlaveStore(ProjectGroup).using(*using).find(222 project_data = IStandbyStore(ProjectGroup).using(*using).find(
223 tables,223 tables,
224 ProjectGroup.translationgroupID == self.id,224 ProjectGroup.translationgroupID == self.id,
225 ProjectGroup.active == True).order_by(ProjectGroup.display_name)225 ProjectGroup.active == True).order_by(ProjectGroup.display_name)
@@ -244,7 +244,7 @@ class TranslationGroup(SQLBase):
244 LibraryFileAlias,244 LibraryFileAlias,
245 LibraryFileContent,245 LibraryFileContent,
246 )246 )
247 distro_data = ISlaveStore(Distribution).using(*using).find(247 distro_data = IStandbyStore(Distribution).using(*using).find(
248 tables, Distribution.translationgroupID == self.id).order_by(248 tables, Distribution.translationgroupID == self.id).order_by(
249 Distribution.display_name)249 Distribution.display_name)
250250
diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py
index 39df58b..03f85e7 100644
--- a/lib/lp/translations/model/translationimportqueue.py
+++ b/lib/lp/translations/model/translationimportqueue.py
@@ -60,7 +60,7 @@ from lp.services.database.constants import (
60from lp.services.database.enumcol import DBEnum60from lp.services.database.enumcol import DBEnum
61from lp.services.database.interfaces import (61from lp.services.database.interfaces import (
62 IMasterStore,62 IMasterStore,
63 ISlaveStore,63 IStandbyStore,
64 IStore,64 IStore,
65 )65 )
66from lp.services.database.sqlbase import quote66from lp.services.database.sqlbase import quote
@@ -1388,13 +1388,13 @@ class TranslationImportQueue:
13881388
1389 return approved_entries1389 return approved_entries
13901390
1391 def _getSlaveStore(self):1391 def _getStandbyStore(self):
1392 """Return the slave store for the import queue.1392 """Return the standby store for the import queue.
13931393
1394 Tests can override this to avoid unnecessary synchronization1394 Tests can override this to avoid unnecessary synchronization
1395 issues.1395 issues.
1396 """1396 """
1397 return ISlaveStore(TranslationImportQueueEntry)1397 return IStandbyStore(TranslationImportQueueEntry)
13981398
1399 def _getBlockableDirectories(self):1399 def _getBlockableDirectories(self):
1400 """Describe all directories where uploads are to be blocked.1400 """Describe all directories where uploads are to be blocked.
@@ -1415,7 +1415,7 @@ class TranslationImportQueue:
1415 """1415 """
1416 importer = getUtility(ITranslationImporter)1416 importer = getUtility(ITranslationImporter)
14171417
1418 store = self._getSlaveStore()1418 store = self._getStandbyStore()
1419 TIQE = TranslationImportQueueEntry1419 TIQE = TranslationImportQueueEntry
1420 result = store.find(1420 result = store.find(
1421 (TIQE.distroseries_id, TIQE.sourcepackagename_id,1421 (TIQE.distroseries_id, TIQE.sourcepackagename_id,
diff --git a/lib/lp/translations/model/vpoexport.py b/lib/lp/translations/model/vpoexport.py
index 4e1f730..11b7c1a 100644
--- a/lib/lp/translations/model/vpoexport.py
+++ b/lib/lp/translations/model/vpoexport.py
@@ -70,7 +70,7 @@ class VPOExportSet:
70 if languagepack:70 if languagepack:
71 conditions.append(POTemplate.languagepack == True)71 conditions.append(POTemplate.languagepack == True)
7272
73 # Use the slave store. We may want to write to the distroseries73 # Use the standby store. We may want to write to the distroseries
74 # to register a language pack, but not to the translation data74 # to register a language pack, but not to the translation data
75 # we retrieve for it.75 # we retrieve for it.
76 # XXX wgrant 2017-03-21: Moved to master to avoid termination76 # XXX wgrant 2017-03-21: Moved to master to avoid termination
diff --git a/lib/lp/translations/scripts/tests/test_translations_to_branch.py b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
index ae6c1c2..e99e417 100644
--- a/lib/lp/translations/scripts/tests/test_translations_to_branch.py
+++ b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
@@ -22,7 +22,7 @@ from lp.registry.interfaces.teammembership import (
22 )22 )
23from lp.registry.model.productseries import ProductSeries23from lp.registry.model.productseries import ProductSeries
24from lp.services.config import config24from lp.services.config import config
25from lp.services.database.interfaces import ISlaveStore25from lp.services.database.interfaces import IStandbyStore
26from lp.services.log.logger import BufferLogger26from lp.services.log.logger import BufferLogger
27from lp.services.scripts.tests import run_script27from lp.services.scripts.tests import run_script
28from lp.testing import (28from lp.testing import (
@@ -162,11 +162,11 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
162 self.assertNotEqual(162 self.assertNotEqual(
163 db_branch.last_mirrored_id,163 db_branch.last_mirrored_id,
164 six.ensure_text(tree.branch.last_revision()))164 six.ensure_text(tree.branch.last_revision()))
165 # The export code works on a Branch from the slave store. It165 # The export code works on a Branch from the standby store. It
166 # shouldn't stop the scan request.166 # shouldn't stop the scan request.
167 slave_series = ISlaveStore(productseries).get(167 standby_series = IStandbyStore(productseries).get(
168 ProductSeries, productseries.id)168 ProductSeries, productseries.id)
169 exporter._exportToBranch(slave_series)169 exporter._exportToBranch(standby_series)
170 self.assertEqual(170 self.assertEqual(
171 db_branch.last_mirrored_id,171 db_branch.last_mirrored_id,
172 six.ensure_text(tree.branch.last_revision()))172 six.ensure_text(tree.branch.last_revision()))
diff --git a/lib/lp/translations/scripts/translations_to_branch.py b/lib/lp/translations/scripts/translations_to_branch.py
index 92f5ca4..c3ef20b 100644
--- a/lib/lp/translations/scripts/translations_to_branch.py
+++ b/lib/lp/translations/scripts/translations_to_branch.py
@@ -39,7 +39,7 @@ from lp.codehosting.vfs import get_rw_server
39from lp.services.config import config39from lp.services.config import config
40from lp.services.database.interfaces import (40from lp.services.database.interfaces import (
41 IMasterStore,41 IMasterStore,
42 ISlaveStore,42 IStandbyStore,
43 )43 )
44from lp.services.helpers import shortlist44from lp.services.helpers import shortlist
45from lp.services.mail.helpers import (45from lp.services.mail.helpers import (
@@ -312,7 +312,7 @@ class ExportTranslationsToBranch(LaunchpadCronScript):
312312
313 self.logger.info("Exporting to translations branches.")313 self.logger.info("Exporting to translations branches.")
314314
315 self.store = ISlaveStore(Product)315 self.store = IStandbyStore(Product)
316316
317 product_join = Join(317 product_join = Join(
318 ProductSeries, Product, ProductSeries.product == Product.id)318 ProductSeries, Product, ProductSeries.product == Product.id)
diff --git a/lib/lp/translations/tests/test_autoapproval.py b/lib/lp/translations/tests/test_autoapproval.py
index b778fac..b567c9d 100644
--- a/lib/lp/translations/tests/test_autoapproval.py
+++ b/lib/lp/translations/tests/test_autoapproval.py
@@ -1154,9 +1154,9 @@ class TestAutoBlocking(TestCaseWithFactory):
1154 super().setUp()1154 super().setUp()
1155 self.queue = TranslationImportQueue()1155 self.queue = TranslationImportQueue()
1156 # Our test queue operates on the master store instead of the1156 # Our test queue operates on the master store instead of the
1157 # slave store so we don't have to synchronize stores.1157 # standby store so we don't have to synchronize stores.
1158 master_store = IMasterStore(TranslationImportQueueEntry)1158 master_store = IMasterStore(TranslationImportQueueEntry)
1159 self.queue._getSlaveStore = FakeMethod(result=master_store)1159 self.queue._getStandbyStore = FakeMethod(result=master_store)
11601160
1161 def _copyTargetFromEntry(self, entry):1161 def _copyTargetFromEntry(self, entry):
1162 """Return a dict representing `entry`'s translation target.1162 """Return a dict representing `entry`'s translation target.
diff --git a/lib/lp/translations/tests/test_translationimportqueue.py b/lib/lp/translations/tests/test_translationimportqueue.py
index 671195a..06abfdb 100644
--- a/lib/lp/translations/tests/test_translationimportqueue.py
+++ b/lib/lp/translations/tests/test_translationimportqueue.py
@@ -12,7 +12,7 @@ from zope.security.proxy import removeSecurityProxy
12from lp.app.enums import InformationType12from lp.app.enums import InformationType
13from lp.app.interfaces.launchpad import ILaunchpadCelebrities13from lp.app.interfaces.launchpad import ILaunchpadCelebrities
14from lp.services.database.interfaces import (14from lp.services.database.interfaces import (
15 ISlaveStore,15 IStandbyStore,
16 IStore,16 IStore,
17 )17 )
18from lp.services.librarianserver.testing.fake import FakeLibrarian18from lp.services.librarianserver.testing.fake import FakeLibrarian
@@ -484,14 +484,14 @@ class TestTranslationImportQueue(TestCaseWithFactory):
484 # reshuffled to see if reportApprovalConflict can be fooled into484 # reshuffled to see if reportApprovalConflict can be fooled into
485 # thinking it's a different error. Make as sure as we can that485 # thinking it's a different error. Make as sure as we can that
486 # entry.error_output is not modified.486 # entry.error_output is not modified.
487 slave_entry = ISlaveStore(entry).get(487 standby_entry = IStandbyStore(entry).get(
488 TranslationImportQueueEntry, entry.id)488 TranslationImportQueueEntry, entry.id)
489 slave_entry.setErrorOutput = FakeMethod()489 standby_entry.setErrorOutput = FakeMethod()
490 slave_entry.reportApprovalConflict(490 standby_entry.reportApprovalConflict(
491 domain, len(templates), reversed(templates))491 domain, len(templates), reversed(templates))
492 self.assertEqual(original_error, slave_entry.error_output)492 self.assertEqual(original_error, standby_entry.error_output)
493 self.assertIn(domain, original_error)493 self.assertIn(domain, original_error)
494 self.assertEqual(0, slave_entry.setErrorOutput.call_count)494 self.assertEqual(0, standby_entry.setErrorOutput.call_count)
495495
496496
497class TestHelpers(TestCaseWithFactory):497class TestHelpers(TestCaseWithFactory):
diff --git a/scripts/get-stacked-on-branches.py b/scripts/get-stacked-on-branches.py
index 9a60b7f..6c15bc0 100755
--- a/scripts/get-stacked-on-branches.py
+++ b/scripts/get-stacked-on-branches.py
@@ -27,7 +27,7 @@ from optparse import OptionParser
2727
28from storm.locals import Not28from storm.locals import Not
2929
30from lp.services.database.interfaces import ISlaveStore30from lp.services.database.interfaces import IStandbyStore
31from lp.services.scripts import execute_zcml_for_scripts31from lp.services.scripts import execute_zcml_for_scripts
3232
3333
@@ -35,7 +35,7 @@ def get_stacked_branches():
35 """Iterate over all branches that, according to the db, are stacked."""35 """Iterate over all branches that, according to the db, are stacked."""
36 # Avoiding circular import.36 # Avoiding circular import.
37 from lp.code.model.branch import Branch37 from lp.code.model.branch import Branch
38 return ISlaveStore(Branch).find(Branch, Not(Branch.stacked_on == None))38 return IStandbyStore(Branch).find(Branch, Not(Branch.stacked_on == None))
3939
4040
41def main():41def main():
diff --git a/utilities/soyuz-sampledata-setup.py b/utilities/soyuz-sampledata-setup.py
index b8cb28e..cde53e9 100755
--- a/utilities/soyuz-sampledata-setup.py
+++ b/utilities/soyuz-sampledata-setup.py
@@ -40,7 +40,7 @@ from lp.registry.interfaces.series import SeriesStatus
40from lp.registry.model.codeofconduct import SignedCodeOfConduct40from lp.registry.model.codeofconduct import SignedCodeOfConduct
41from lp.services.database.interfaces import (41from lp.services.database.interfaces import (
42 IMasterStore,42 IMasterStore,
43 ISlaveStore,43 IStandbyStore,
44 )44 )
45from lp.services.scripts.base import LaunchpadScript45from lp.services.scripts.base import LaunchpadScript
46from lp.soyuz.enums import SourcePackageFormat46from lp.soyuz.enums import SourcePackageFormat
@@ -78,7 +78,7 @@ def check_preconditions(options):
78 This script must not run on a production server, or anything78 This script must not run on a production server, or anything
79 remotely like it.79 remotely like it.
80 """80 """
81 store = ISlaveStore(ComponentSelection)81 store = IStandbyStore(ComponentSelection)
8282
83 # Just a guess, but dev systems aren't likely to have ids this high83 # Just a guess, but dev systems aren't likely to have ids this high
84 # in this table. Production data does.84 # in this table. Production data does.

Subscribers

People subscribed via source and target branches

to status/vote changes: