Are Providers at all memoized/cached? are ValueSou...
# community-support
c
Are Providers at all memoized/cached? are ValueSources? or will they always be re-retrieved unless I manually handle that?
g
AFAIK, it depends on the Provider (implementation). In the case of `ValueSource`s, the returned value is memoized/cached. However, in the case of
provider { }
, for example, it isn't.
c
how long is the cache? one build?
this isn't something I can see a reason to do more than once a day (I think this thing makes an http call, trying to figure that out now)
yep, found it, this is definitely doing an http request
but I doubt this value changes for anyone more than .... yearly, lol
or more
g
ValueSource is queried once per build. It's cached for that build, but queried on the next build, since it's taken into consideration (as an input) for whether configuration cache can be re-used or not for that build. What kind of value are we talking about and how will you use it? There's also
TextResourceFactory.fromUri
, but I'm not sure what its behavior is if you need it at configuration time. I've only used it at execution time so far (example).
v
ValueSource is queried once per build
That's not fully true. If the CC entry cannot be reused, it is evaluated twice in that build, once to find the CC entry cannot be reused and then again to create the new CC entry.
or will they always be re-retrieved unless I manually handle that?
You can use a
Property
to create a cached `Provider`: https://github.com/gradle/gradle/issues/25550 But this is not something persisted, just within one build execution.
g
Hmm you're right. I didn't know that. I think it could be mentioned in the docs. The current <https://docs.gradle.org/current/javadoc/org/gradle/api/provider/ValueSource.html#obtain() |ValueSource.obtain javadoc> only says
This method is only called if the provider value is requested and only once in that case.
I couldn't find an open issue or PR. Unless you know of one, I can open it
v
Issue for what? That it is invoked twice, or that the docs don't mention that?
c
The resource is an http or SSH query of some kind I don't know how the latter works. Unfortunately it's hidden behind a library. Which means I don't have direct access to it.
v
For the HTTP one you could maybe instead use an Ivy repository and let Gradle download the file, then it should land in the Gradle artifacts cache and thus be reused even across invocations or even projects.
👍🏻 1
g
@Vampire issue about the docs not mentioning it
v
I don't remember an issue about it. I thought it was documented, but do not find it. Maybe I just observed or otherwise learned it.
Tell me if you opened an issue, I'll thumbs-up it 🙂
🙂 1
c
No I cannot. Just for clarification this is the request that git remote show origin does to show things like the head branch. So it is not a value that I can control where it comes from.
g
Do you need it at configuration time?
v
Hopefully, otherwise the discussion would be halfway pointless 😄
c
Yes I do because I plan on using it to set the version ... property (which is not a Property)
v
... yet
c
Correct but that isn't relevant either way I just didn't want to be confusing about that statement
Either way that would be a configuration time setting
v
Well, you probably need to do some cache yourself. Maybe using a
ValueSource
, in there read the result from some text file where you persisted it, if not found doing the request and persisting it. Something like that.
c
Yep, sounds like it
Also I did actually read the javadoc on this and it was not very clear in my opinion about how it was determining how often that value was requeried.
v
I'd say that is what @Gabriel Feo's issue will be about. For each provider you create for that value source with
providers.of
the value will be calculated once or twice. Twice if a CC entry exists but cannot be reused, the first time when determining whether the entry can be reused, the second time when the new CC entry is calculated.
c
Yes, I know. I was just verifying that that was my opinion. How often are callable providers queried? Every time they are accessed?
v
What are "callable providers"? A provider is queried when you query it. How far down the chain depends on the chain. The provider you create from a value source for example caches the value source result so the value source is only obtained once. If you have a
Property
in the chain that has
finalizeValueOnRead()
or
finalizeValue()
, it will also only be calculated once and then the same result returned. ...
c
Callable is an interface. It's the interface that is used when you write a lambda instead of a value source
Well, the interface that is used if you're not using one of the other default providers... Obviously any callable will do as long as you implement the interface
So what I hear you saying is that it will be run every time "you" (whomever that is) call get
So if you use said provider in 13 different places that callable is going to be called 13 different times
v
I know the interface
Callable
, but I don't know what you mean by "callable provider"
c
To be contrasted with other kinds of providers as I don't have a better term
I wouldn't consider an environment provider that kind of provider or a value source One
v
Don't use a term, show an example 🙂
c
I'm on my phone right now it's kind of hard to write code on my phone
v
Then I'm afraid I cannot answer, because I'm still unsure what exactly you mean
c
You don't know how to make a provider from a function? You literally just showed how to do it
v
So you mean
provider { "foo" }
?
Yes, this is evaluated each time you
get()
it
c
Yes that is exactly what I mean
v
See the issue about cached provider I posted above
c
Do you think that the aforementioned issue also needs to mention that it needs to work for value sources?
now I'm on my computer, think about that issue, and the comment I just updated. Do you think I should make a second issue? I think what you want is memoize, or perhaps just a simple
valueSource { "foo" }
. which you could also do with a kotlin extension. I'm not saying that's not useful.
v
Yes, just have seen your comment and answered exactly that. 😄 What I want is a cached provider with cache period the lifetime of the build. If you prefer to call that memoization feel free to, for me this is also a caching of the calculated result. 🙂
valueSource { "foo" }
is pretty inappropriate, as
ValueSource
is for doing CC-incompatible things or accessing things that should not end up as CC inputs and also will be evaluated each build, even if CC is reused and even twice if CC entry is present but not reused, so a totally different topic again.
c
I mean, memoization is that, you're not wrong, but it's a super simple form of caching, I want something more powerful 😉
anyways, off to read the comment 😉
ok, I added a new ticket 😉 feel free to comment if you want
👌 1