In my _fetch subroutine, I would like to force caching by setting the beresp.ttl. Normally one would do this like so:
set beresp.ttl = 900s;
Where the 900s represents a varnish data type called a duration (aka RTIME).
In my case, though, I want to set the TTL contextually, by reading a response header value and setting the ttl on the basis of that value, something like:
set beresp.http.x-myduration = beresp.http.x-my-custom-header; # (contains a string like "900")
# Can't do this because a string cannot be converted to duration.
set beresp.ttl = beresp.http.x-myduration + "s";
# Can't do this because it appears std.duration() is not available in Fastly
# despite being in varnish since v5 at least???
set beresp.ttl = std.duration(beresp.http.x-myduration + "s", 111s); #111s is the fallback argument.
Given that std.duration() seems to be missing, how are people using strings to set ttl? It’s hard to imagine there is no way to cast strings to RTIME/duration.
In regards to trimming the header before converting the value to an integer, we have a fairly broad library for string manipulation that might be helpful Strings | Fastly Documentation
Also, out of curiosity, we’d love to know more about what you’re building – just in case it’s a good feature request for the future. <3
Hi @aspires and thank you for your reply. I appreciate it. I am a bit confused though, since ttl wants to receive a duration (300s, 2m, 3w etc), not an integer. The error I was getting when trying to set it was that it could not convert to RTIME (duration).
It seems like you are asserting that .ttl will accept a pure integer argument (without the s, m, w, h portion) and cast that to a duration internally? In which case, I suppose .ttl would treat 300 as though it were 300s?
If that is what you are asserting, and I don’t need to cast to the expected data type (RTIME/duration) but can provide an integer instead then yes, converting the string to an integer will be sufficient. It seems std.atoi() works for this as well the the std.strtol you mention.
Now, just out of curiosity, why doesn’t Fastly include std.duration()? It’s been in varnish since v5. I’m sure there’s a good reason so I am curious about that.
@apotek It looks like I misread your original request, my apologies. Disregard my earlier suggestion.
Fastly’s VCL forked from the upstream VCL in v2.1, so don’t inherit upstream contributions by default unless they’re intentionally built into the ecosystem.
After looking through the Varnish docs (correct me if I’m not looking at the right docs), setting a variable with std.time might be the closest approximation available, though it’s not as feature-rich at first glance.
It also might make sense to jump on a call if I’m really not grok-ing what you’re aiming to do.
Thank you @aspires and @ibrocardfastly. @aspires it was really helpful to know I can’t use varnish documentation for my work with Fastly since it was forked so long ago and to know that std.duration() does in fact, not exist (and not that I was doing something wrong).
@ibrocardfastly, what confuses me about your answer is that the function you link to parse_time_delta documents returning an integer not an RTIME/Duration type. It seems to actually do almost the opposite, ie it will parse a string of either just seconds “600” or a string duration “10m” into an integer (ie “10m” would become int 600).
Varnish requires the ttl property to be defined as RTIME/duration, but I wonder if that happened after varnish 2.0. Because in my Fastly testing it seems that I am allowed to set .ttl to a bare int. So, within varnish 2/Fastly it seems I might not need std.duration() but can simply convert my string to an integer and then set .ttl to an int. That’s what it seems like to me at the moment at least.