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