Coverage for /builds/BuildGrid/buildgrid/buildgrid/server/actioncache/service.py: 100.00%

49 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-06-11 15:37 +0000

1# Copyright (C) 2018 Bloomberg LP 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# <http://www.apache.org/licenses/LICENSE-2.0> 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15 

16""" 

17ActionCacheService 

18================== 

19 

20Allows clients to manually query/update the action cache. 

21""" 

22 

23import logging 

24from typing import Union, cast 

25 

26import grpc 

27 

28import buildgrid.server.context as context_module 

29from buildgrid._exceptions import NotFoundError 

30from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import DESCRIPTOR as RE_DESCRIPTOR 

31from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import ( 

32 ActionResult, 

33 GetActionResultRequest, 

34 UpdateActionResultRequest, 

35) 

36from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2_grpc import ( 

37 ActionCacheServicer, 

38 add_ActionCacheServicer_to_server, 

39) 

40from buildgrid.server.actioncache.caches.action_cache_abc import ActionCacheABC 

41from buildgrid.server.actioncache.instance import ActionCache 

42from buildgrid.server.auth.manager import authorize 

43from buildgrid.server.instance import instanced 

44from buildgrid.server.metrics_names import ( 

45 AC_CACHE_HITS_METRIC_NAME, 

46 AC_CACHE_MISSES_METRIC_NAME, 

47 AC_GET_ACTION_RESULT_TIME_METRIC_NAME, 

48 AC_UPDATE_ACTION_RESULT_TIME_METRIC_NAME, 

49) 

50from buildgrid.server.metrics_utils import DurationMetric, publish_counter_metric 

51from buildgrid.server.request_metadata_utils import printable_request_metadata 

52from buildgrid.server.servicer import InstancedServicer 

53from buildgrid.server.utils.decorators import handle_errors_unary_unary, track_request_id 

54 

55LOGGER = logging.getLogger(__name__) 

56 

57 

58class ActionCacheService(ActionCacheServicer, InstancedServicer[Union[ActionCache, ActionCacheABC]]): 

59 REGISTER_METHOD = add_ActionCacheServicer_to_server 

60 FULL_NAME = RE_DESCRIPTOR.services_by_name["ActionCache"].full_name 

61 

62 @instanced(lambda r: cast(str, r.instance_name)) 

63 @authorize 

64 @context_module.metadatacontext() 

65 @track_request_id 

66 @handle_errors_unary_unary(ActionResult) 

67 def GetActionResult(self, request: GetActionResultRequest, context: grpc.ServicerContext) -> ActionResult: 

68 LOGGER.info( 

69 f"GetActionResult request from [{context.peer()}] " 

70 f"([{printable_request_metadata(context.invocation_metadata())}])" 

71 ) 

72 

73 try: 

74 instance = self.get_instance(request.instance_name) 

75 with DurationMetric(AC_GET_ACTION_RESULT_TIME_METRIC_NAME, request.instance_name, instanced=True): 

76 action_result = instance.get_action_result(request.action_digest) 

77 publish_counter_metric(AC_CACHE_HITS_METRIC_NAME, 1, {"instance-name": request.instance_name}) 

78 return action_result 

79 

80 except NotFoundError: 

81 publish_counter_metric(AC_CACHE_MISSES_METRIC_NAME, 1, {"instance-name": request.instance_name}) 

82 raise 

83 

84 @instanced(lambda r: cast(str, r.instance_name)) 

85 @authorize 

86 @context_module.metadatacontext() 

87 @track_request_id 

88 @handle_errors_unary_unary(ActionResult) 

89 def UpdateActionResult(self, request: UpdateActionResultRequest, context: grpc.ServicerContext) -> ActionResult: 

90 LOGGER.info( 

91 f"UpdateActionResult request from [{context.peer()}] " 

92 f"([{printable_request_metadata(context.invocation_metadata())}])" 

93 ) 

94 

95 instance = self.get_instance(request.instance_name) 

96 with DurationMetric(AC_UPDATE_ACTION_RESULT_TIME_METRIC_NAME, request.instance_name, instanced=True): 

97 instance.update_action_result(request.action_digest, request.action_result) 

98 return request.action_result