Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: appengine/monorail/framework/reap.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """A class to handle cron requests to expunge doomed and deletable projects."""
7
8 import logging
9 import time
10
11 from framework import jsonfeed
12
13 RUN_DURATION_LIMIT = 50 * 60 # 50 minutes
14
15
16 class Reap(jsonfeed.InternalTask):
17 """Look for doomed and deletable projects and delete them."""
18
19 def HandleRequest(self, mr):
20 """Update/Delete doomed and deletable projects as needed.
21
22 Args:
23 mr: common information parsed from the HTTP request.
24
25 Returns:
26 Results dictionary in JSON format. The JSON will look like this:
27 {
28 'doomed_project_ids': <int>,
29 'expunged_project_ids': <int>
30 }
31 doomed_project_ids are the projects which have been marked as deletable.
32 expunged_project_ids are the projects that have either been completely
33 expunged or are in the midst of being expunged.
34 """
35 doomed_project_ids = self._MarkDoomedProjects(mr.cnxn)
36 expunged_project_ids = self._ExpungeDeletableProjects(mr.cnxn)
37 return {
38 'doomed_project_ids': doomed_project_ids,
39 'expunged_project_ids': expunged_project_ids,
40 }
41
42 def _MarkDoomedProjects(self, cnxn):
43 """No longer needed projects get doomed, and this marks them deletable."""
44 now = int(time.time())
45 doomed_project_rows = self.services.project.project_tbl.Select(
46 cnxn, cols=['project_id'],
47 # We only match projects with real timestamps and not delete_time = 0.
48 where=[('delete_time < %s', [now]), ('delete_time != %s', [0])],
49 state='archived', limit=1000)
50 doomed_project_ids = [row[0] for row in doomed_project_rows]
51 for project_id in doomed_project_ids:
52 self.services.project.MarkProjectDeletable(
53 cnxn, project_id, self.services.config)
54
55 return doomed_project_ids
56
57 def _ExpungeDeletableProjects(self, cnxn):
58 """Chip away at deletable projects until they are gone."""
59 request_deadline = time.time() + RUN_DURATION_LIMIT
60
61 deletable_project_rows = self.services.project.project_tbl.Select(
62 cnxn, cols=['project_id'], state='deletable', limit=100)
63 deletable_project_ids = [row[0] for row in deletable_project_rows]
64 # expunged_project_ids will contain projects that have either been
65 # completely expunged or are in the midst of being expunged.
66 expunged_project_ids = set()
67 for project_id in deletable_project_ids:
68 for _part in self._ExpungeParts(cnxn, project_id):
69 expunged_project_ids.add(project_id)
70 if time.time() > request_deadline:
71 return list(expunged_project_ids)
72
73 return list(expunged_project_ids)
74
75 def _ExpungeParts(self, cnxn, project_id):
76 """Delete all data from the specified project, one part at a time.
77
78 This method purges all data associated with the specified project. The
79 following is purged:
80 * All issues of the project.
81 * Project config.
82 * Saved queries.
83 * Filter rules.
84 * Former locations.
85 * Local ID counters.
86 * Quick edit history.
87 * Item stars.
88 * Project from the DB.
89
90 Returns a generator whose return values can be either issue
91 ids or the specified project id. The returned values are intended to be
92 iterated over and not read.
93 """
94 # Purge all issues of the project.
95 while True:
96 issue_id_rows = self.services.issue.issue_tbl.Select(
97 cnxn, cols=['id'], project_id=project_id, limit=1000)
98 issue_ids = [row[0] for row in issue_id_rows]
99 for issue_id in issue_ids:
100 self.services.issue_star.ExpungeStars(cnxn, issue_id)
101 self.services.issue.ExpungeIssues(cnxn, issue_ids)
102 yield issue_ids
103 break
104
105 # All project purge functions are called with cnxn and project_id.
106 project_purge_functions = (
107 self.services.config.ExpungeConfig,
108 self.services.features.ExpungeSavedQueriesExecuteInProject,
109 self.services.features.ExpungeFilterRules,
110 self.services.issue.ExpungeFormerLocations,
111 self.services.issue.ExpungeLocalIDCounters,
112 self.services.features.ExpungeQuickEditHistory,
113 self.services.project_star.ExpungeStars,
114 self.services.project.ExpungeProject,
115 )
116
117 for f in project_purge_functions:
118 f(cnxn, project_id)
119 yield project_id
OLDNEW
« no previous file with comments | « appengine/monorail/framework/ratelimiter.py ('k') | appengine/monorail/framework/registerpages_helpers.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698