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

36 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""" 

17Action Cache 

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

19 

20Implements an in-memory action Cache 

21""" 

22 

23import logging 

24 

25from buildgrid._exceptions import NotFoundError, RetriableError 

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

27from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import ActionResult, Digest, DigestFunction 

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

29from buildgrid.server.metrics_names import ( 

30 AC_GET_ACTION_RESULT_EXCEPTION_COUNT_METRIC_NAME, 

31 AC_UPDATE_ACTION_RESULT_EXCEPTION_COUNT_METRIC_NAME, 

32) 

33from buildgrid.server.metrics_utils import ExceptionCounter 

34from buildgrid.server.servicer import Instance 

35from buildgrid.utils import get_hash_type 

36 

37LOGGER = logging.getLogger(__name__) 

38 

39 

40class ActionCache(Instance): 

41 SERVICE_NAME = RE_DESCRIPTOR.services_by_name["ActionCache"].full_name 

42 

43 def __init__(self, cache: ActionCacheABC) -> None: 

44 """Initialises a new ActionCache instance. 

45 

46 Args: 

47 cache (ActionCacheABC): The cache to use to store results. 

48 

49 """ 

50 self._cache = cache 

51 

52 # --- Public API --- 

53 

54 def start(self) -> None: 

55 self._cache.start() 

56 

57 def stop(self) -> None: 

58 self._cache.stop() 

59 LOGGER.info(f"Stopped ActionCache instance for '{self._instance_name}") 

60 

61 @property 

62 def allow_updates(self) -> bool: 

63 return self._cache.allow_updates 

64 

65 def hash_type(self) -> "DigestFunction.Value.ValueType": 

66 return get_hash_type() 

67 

68 def set_instance_name(self, instance_name: str) -> None: 

69 super().set_instance_name(instance_name) 

70 self._cache.set_instance_name(instance_name) 

71 

72 get_action_ignored_exceptions = (NotFoundError, RetriableError) 

73 

74 @ExceptionCounter( 

75 AC_GET_ACTION_RESULT_EXCEPTION_COUNT_METRIC_NAME, ignored_exceptions=get_action_ignored_exceptions 

76 ) 

77 def get_action_result(self, action_digest: Digest) -> ActionResult: 

78 """Retrieves the cached result for an Action. 

79 

80 If there is no cached result found, returns None. 

81 

82 Args: 

83 action_digest (Digest): The digest of the Action to retrieve the 

84 cached result of. 

85 

86 """ 

87 return self._cache.get_action_result(action_digest) 

88 

89 update_action_ignored_exceptions = (NotFoundError, RetriableError) 

90 

91 @ExceptionCounter( 

92 AC_UPDATE_ACTION_RESULT_EXCEPTION_COUNT_METRIC_NAME, ignored_exceptions=update_action_ignored_exceptions 

93 ) 

94 def update_action_result(self, action_digest: Digest, action_result: ActionResult) -> None: 

95 """Stores a result for an Action in the cache. 

96 

97 If the result has a non-zero exit code and `cache_failed_actions` is False 

98 for this cache, the result is not cached. 

99 

100 Args: 

101 action_digest (Digest): The digest of the Action whose result is 

102 being cached. 

103 action_result (ActionResult): The result to cache for the given 

104 Action digest. 

105 

106 """ 

107 self._cache.update_action_result(action_digest, action_result)