in src/buildstream/element.py [0:0]
def _load_artifact(self, *, pull, strict=None):
context = self._get_context()
if strict is None:
strict = context.get_strict()
pull_buildtrees = context.pull_buildtrees and not self._get_workspace()
# First check whether we already have the strict artifact in the local cache
artifact = Artifact(
self,
context,
strict_key=self.__strict_cache_key,
strong_key=self.__strict_cache_key,
weak_key=self.__weak_cache_key,
)
artifact.query_cache()
self.__pull_pending = False
if not pull and not artifact.cached(buildtree=pull_buildtrees):
if self.__artifacts.has_fetch_remotes(plugin=self) and not self._get_workspace():
# Artifact is not completely available in cache and artifact remote server is available.
# Stop artifact loading here as pull is required to proceed.
self.__pull_pending = True
# Attempt to pull artifact with the strict cache key
pulled = pull and artifact.pull(pull_buildtrees=pull_buildtrees)
# Ignore failed build artifacts if a retry was requested
ignore_failed_artifact = context.build and context.build_retry_failed
if artifact.cached() or strict:
if artifact.cached() and ignore_failed_artifact:
success, _, _ = artifact.load_build_result()
if not success:
self.info(
"Discarded failed build",
detail="Discarded '{}'\n".format(artifact.strong_key)
+ "because retrying failed builds is enabled.",
)
artifact = Artifact(
self,
context,
strong_key=self.__cache_key,
strict_key=self.__strict_cache_key,
weak_key=self.__weak_cache_key,
)
artifact._cached = False
pulled = False
self.__artifact = artifact
return pulled
elif self.__pull_pending:
return False
# In non-strict mode retry with weak cache key
artifact = Artifact(self, context, strict_key=self.__strict_cache_key, weak_key=self.__weak_cache_key)
artifact.query_cache()
# Attempt to pull artifact with the weak cache key
pulled = pull and artifact.pull(pull_buildtrees=pull_buildtrees)
# Automatically retry building failed builds in non-strict mode, because
# dependencies may have changed since the last build which might cause this
# failed build to succeed.
#
# When not building (e.g. `bst show`, `bst artifact push` etc), we do not drop
# the failed artifact, the retry only occurs at build time.
#
if context.build and artifact.cached():
success, _, _ = artifact.load_build_result()
if not success:
#
# If we could resolve the stong cache key for this element at this time,
# we could compare the artifact key against the resolved strong key.
#
# If we could assert that artifact state is never consulted in advance
# of resolving the strong key, then we could discard the loaded artifact
# at that time instead.
#
# Since neither of these are true, we settle for always retrying a failed
# build in non-strict mode unless the failed artifact's strong key is
# equal to the resolved strict key.
#
if ignore_failed_artifact or artifact.strong_key != self.__strict_cache_key:
if ignore_failed_artifact:
reason = "because retrying failed builds is enabled."
else:
reason = "in non strict mode because intermediate dependencies may have changed."
self.info(
"Discarded failed build",
detail="Discarded '{}'\n{}".format(artifact.strong_key, reason),
)
artifact = Artifact(
self,
context,
strict_key=self.__strict_cache_key,
weak_key=self.__weak_cache_key,
)
artifact._cached = False
pulled = False
self.__artifact = artifact
return pulled