blob: 53e87ec0d0fdcc6a70ef2be1e17f80dcf04c100d [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed 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 servlet that implements the backend of issues search.
7
8The GET request to a backend search has the same query string
9parameters as the issue list servlet. But, instead of rendering a
10HTML page, the backend search handler returns a JSON response with a
11list of matching, sorted issue IID numbers from this shard that are
12viewable by the requesting user.
13
14Each backend search request works within a single shard. Each
15besearch backend job can access any single shard while processing a request.
16
17The current user ID must be passed in from the frontend for permission
18checking. The user ID for the special "me" term can also be passed in
19(so that you can view another user's dashboard and "me" will refer to
20them).
21"""
22from __future__ import print_function
23from __future__ import division
24from __future__ import absolute_import
25
26import logging
27import time
28
29from framework import jsonfeed
30from search import backendsearchpipeline
31from tracker import tracker_constants
32
33
34class BackendSearch(jsonfeed.InternalTask):
35 """JSON servlet for issue search in a GAE backend."""
36
37 CHECK_SAME_APP = True
38 _DEFAULT_RESULTS_PER_PAGE = tracker_constants.DEFAULT_RESULTS_PER_PAGE
39
40 def HandleRequest(self, mr):
41 """Search for issues and respond with the IIDs of matching issues.
42
43 Args:
44 mr: common information parsed from the HTTP request.
45
46 Returns:
47 Results dictionary in JSON format.
48 """
49 # Users are never logged into backends, so the frontends tell us.
50 logging.info('query_project_names is %r', mr.query_project_names)
51 pipeline = backendsearchpipeline.BackendSearchPipeline(
52 mr, self.services, self._DEFAULT_RESULTS_PER_PAGE,
53 mr.query_project_names, mr.specified_logged_in_user_id,
54 mr.specified_me_user_ids)
55 pipeline.SearchForIIDs()
56
57 start = time.time()
58 # Backends work in parallel to precache issues that the
59 # frontend is very likely to need.
60 _prefetched_issues = self.services.issue.GetIssues(
61 mr.cnxn, pipeline.result_iids[:mr.start + mr.num],
62 shard_id=mr.shard_id)
63 logging.info('prefetched and memcached %d issues in %d ms',
64 len(pipeline.result_iids[:mr.start + mr.num]),
65 int(1000 * (time.time() - start)))
66
67 if pipeline.error:
68 error_message = pipeline.error.message
69 else:
70 error_message = None
71
72 return {
73 'unfiltered_iids': pipeline.result_iids,
74 'search_limit_reached': pipeline.search_limit_reached,
75 'error': error_message,
76 }