Coverage for /builds/BuildGrid/buildgrid/buildgrid/client/actioncache.py: 33.33%

42 statements  

« prev     ^ index     » next       coverage.py v6.4.1, created at 2022-06-22 21:04 +0000

1# Copyright (C) 2019 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 

16from contextlib import contextmanager 

17 

18import buildgrid.server.context as context_module 

19from buildgrid._exceptions import NotFoundError 

20from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2, remote_execution_pb2_grpc 

21from buildgrid.client.cas import GrpcRetrier 

22 

23 

24@contextmanager 

25def query(channel, 

26 instance=None, 

27 retries: int = 0, 

28 max_backoff: int = 64, 

29 should_backoff: bool = True): 

30 """Context manager generator for the :class:`ActionCacheClient` class.""" 

31 client = ActionCacheClient(channel, 

32 instance=instance, 

33 retries=retries, 

34 max_backoff=max_backoff, 

35 should_backoff=should_backoff) 

36 try: 

37 yield client 

38 finally: 

39 client.close() 

40 

41 

42class ActionCacheClient: 

43 """Remote ActionCache service client helper. 

44 

45 The :class:`ActionCacheClient` class comes with a generator factory function 

46 that can be used together with the `with` statement for context management:: 

47 

48 from buildgrid.client.actioncache import query 

49 

50 with query(channel, instance='build') as action_cache: 

51 digest, action_result = action_cache.get(action_digest) 

52 """ 

53 

54 def __init__(self, 

55 channel, 

56 instance=None, 

57 retries: int = 0, 

58 max_backoff: int = 64, 

59 should_backoff: bool = True): 

60 """Initializes a new :class:`ActionCacheClient` instance. 

61 

62 Args: 

63 channel (grpc.Channel): a gRPC channel to the ActionCache endpoint. 

64 instance (str, optional): the targeted instance's name. 

65 """ 

66 self._grpc_retrier = (GrpcRetrier(retries=retries, 

67 max_backoff=max_backoff, 

68 should_backoff=should_backoff)) 

69 self.channel = channel 

70 

71 self.instance_name = instance 

72 

73 self.__actioncache_stub = remote_execution_pb2_grpc.ActionCacheStub(self.channel) 

74 

75 # --- Public API --- 

76 

77 def get(self, action_digest): 

78 """Attempt to retrieve cached :obj:`ActionResult` for : given obj:`Action`. 

79 """ 

80 try: 

81 return self._grpc_retrier.retry(self._get, action_digest) 

82 except NotFoundError: 

83 return None 

84 

85 def update(self, action_digest, action_result): 

86 """Attempt to map in cache an :obj:`Action` to an :obj:`ActionResult`. 

87 """ 

88 try: 

89 return self._grpc_retrier.retry(self._update, action_digest, action_result) 

90 except NotFoundError: 

91 return None 

92 

93 def _get(self, action_digest): 

94 """Retrieves the cached :obj:`ActionResult` for a given :obj:`Action`. 

95 

96 Args: 

97 action_digest (:obj:`Digest`): the action's digest to query. 

98 

99 Returns: 

100 :obj:`ActionResult`: the cached result or None if not found. 

101 

102 Raises: 

103 grpc.RpcError: on any network or remote service error. 

104 """ 

105 request = remote_execution_pb2.GetActionResultRequest() 

106 if self.instance_name: 

107 request.instance_name = self.instance_name 

108 request.action_digest.CopyFrom(action_digest) 

109 

110 return (self.__actioncache_stub.GetActionResult(request, 

111 metadata=context_module.metadata_list())) 

112 

113 def _update(self, action_digest, action_result): 

114 """Maps in cache an :obj:`Action` to an :obj:`ActionResult`. 

115 

116 Args: 

117 action_digest (:obj:`Digest`): the action's digest to update. 

118 action_result (:obj:`ActionResult`): the action's result. 

119 

120 Returns: 

121 :obj:`ActionResult`: the cached result or None on failure. 

122 

123 Raises: 

124 grpc.RpcError: on any network or remote service error. 

125 """ 

126 request = remote_execution_pb2.UpdateActionResultRequest() 

127 if self.instance_name: 

128 request.instance_name = self.instance_name 

129 request.action_digest.CopyFrom(action_digest) 

130 request.action_result.CopyFrom(action_result) 

131 

132 return (self.__actioncache_stub.UpdateActionResult(request, 

133 metadata=context_module.metadata_list())) 

134 

135 def close(self): 

136 """Closes the underlying connection stubs.""" 

137 self.__actioncache_stub = None