Skip to content

Commit a5abede

Browse files
committed
Refactor retry logic with macro, add retry to list()
1 parent 1da8e58 commit a5abede

File tree

2 files changed

+43
-46
lines changed

2 files changed

+43
-46
lines changed

src/helpers.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,28 @@ function set_api_versions!(ctx::KuberContext; override=nothing, verbose::Bool=fa
230230
ctx.initialized = true
231231
nothing
232232
end
233+
234+
"""
235+
Retry function `f` for `max_tries` number of times if function fails with `IOError`
236+
"""
237+
function retry_on_error(f::Function; max_tries=1)
238+
@repeat max_tries try
239+
return f()
240+
catch e
241+
@retry if isa(e, IOError)
242+
@debug("Retrying Kubernetes API call ...")
243+
sleep(2)
244+
end
245+
end
246+
end
247+
248+
"""
249+
Macro to retry an expression on `IOError`. Note that the variable `max_tries` needs to be inscope for this to work.
250+
"""
251+
macro retry_on_error(e)
252+
esc(quote
253+
retry_on_error(;max_tries=max_tries) do
254+
$(e)
255+
end
256+
end)
257+
end

src/simpleapi.jl

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ end
2323
_api_function(name::Symbol) = isdefined(@__MODULE__, name) ? eval(name) : nothing
2424
_api_function(name) = _api_function(Symbol(name))
2525

26-
function list(ctx::KuberContext, O::Symbol, name::String; apiversion::Union{String,Nothing}=nothing, namespace::Union{String,Nothing}=ctx.namespace, kwargs...)
26+
function list(ctx::KuberContext, O::Symbol, name::String; apiversion::Union{String,Nothing}=nothing, namespace::Union{String,Nothing}=ctx.namespace, max_tries::Int=1, kwargs...)
2727
ctx.initialized || set_api_versions!(ctx)
2828

2929
apictx = _get_apictx(ctx, O, apiversion)
@@ -32,17 +32,17 @@ function list(ctx::KuberContext, O::Symbol, name::String; apiversion::Union{Stri
3232

3333
if allnamespaces
3434
apicall = eval(Symbol("list$(O)ForAllNamespaces"))
35-
return apicall(apictx, name; kwargs...)
35+
return @retry_on_error apicall(apictx, name; kwargs...)
3636
elseif namespaced
3737
apicall = eval(Symbol("listNamespaced$O"))
38-
return apicall(apictx, name, namespace; kwargs...)
38+
return @retry_on_error apicall(apictx, name, namespace; kwargs...)
3939
else
4040
apicall = eval(Symbol("list$O"))
41-
return apicall(apictx, name; kwargs...)
41+
return @retry_on_error apicall(apictx, name; kwargs...)
4242
end
4343
end
4444

45-
function list(ctx::KuberContext, O::Symbol; apiversion::Union{String,Nothing}=nothing, namespace::Union{String,Nothing}=ctx.namespace, kwargs...)
45+
function list(ctx::KuberContext, O::Symbol; apiversion::Union{String,Nothing}=nothing, namespace::Union{String,Nothing}=ctx.namespace, max_tries::Int=1, kwargs...)
4646
ctx.initialized || set_api_versions!(ctx)
4747

4848
apictx = _get_apictx(ctx, O, apiversion)
@@ -51,13 +51,13 @@ function list(ctx::KuberContext, O::Symbol; apiversion::Union{String,Nothing}=no
5151

5252
if allnamespaces
5353
apicall = eval(Symbol("list$(O)ForAllNamespaces"))
54-
return apicall(apictx; kwargs...)
54+
return @retry_on_error apicall(apictx; kwargs...)
5555
elseif namespaced
5656
apicall = eval(Symbol("listNamespaced$O"))
57-
return apicall(apictx, namespace; kwargs...)
57+
return @retry_on_error apicall(apictx, namespace; kwargs...)
5858
else
5959
apicall = eval(Symbol("list$O"))
60-
return apicall(apictx; kwargs...)
60+
return @retry_on_error apicall(apictx; kwargs...)
6161
end
6262
end
6363

@@ -66,23 +66,9 @@ function get(ctx::KuberContext, O::Symbol, name::String; apiversion::Union{Strin
6666

6767
apictx = _get_apictx(ctx, O, apiversion)
6868
if (apicall = _api_function("read$O")) !== nothing
69-
@repeat max_tries try
70-
return apicall(apictx, name; kwargs...)
71-
catch e
72-
@retry if isa(e, IOError)
73-
@debug("Retrying ", nameof(apicall))
74-
sleep(2)
75-
end
76-
end
69+
return @retry_on_error apicall(apictx, name; kwargs...)
7770
elseif (apicall = _api_function("readNamespaced$O")) !== nothing
78-
@repeat max_tries try
79-
return apicall(apictx, name, ctx.namespace; kwargs...)
80-
catch e
81-
@retry if isa(e, IOError)
82-
@debug("Retrying ", nameof(apicall))
83-
sleep(2)
84-
end
85-
end
71+
return @retry_on_error apicall(apictx, name, ctx.namespace; kwargs...)
8672
else
8773
throw(ArgumentError("No API functions could be located using :$O"))
8874
end
@@ -95,23 +81,9 @@ function get(ctx::KuberContext, O::Symbol; apiversion::Union{String,Nothing}=not
9581
apiname = "list$O"
9682
namespace === nothing && (apiname *= "ForAllNamespaces")
9783
if (apicall = _api_function(apiname)) !== nothing
98-
@repeat max_tries try
99-
return apicall(apictx; labelSelector=label_selector)
100-
catch e
101-
@retry if isa(e, IOError)
102-
@debug("Retrying ", nameof(apicall))
103-
sleep(2)
104-
end
105-
end
84+
return @retry_on_error apicall(apictx; labelSelector=label_selector)
10685
elseif (apicall = _api_function("listNamespaced$O")) !== nothing
107-
@repeat max_tries try
108-
return apicall(apictx, namespace; labelSelector=label_selector)
109-
catch e
110-
@retry if isa(e, IOError)
111-
@debug("Retrying ", nameof(apicall))
112-
sleep(2)
113-
end
114-
end
86+
return @retry_on_error apicall(apictx, namespace; labelSelector=label_selector)
11587
else
11688
throw(ArgumentError("No API functions could be located using :$O"))
11789
end
@@ -127,9 +99,9 @@ function put!(ctx::KuberContext, O::Symbol, d::Dict{String,Any})
12799

128100
apictx = _get_apictx(ctx, O, get(d, "apiVersion", nothing))
129101
if (apicall = _api_function("create$O")) !== nothing
130-
return apicall(apictx, d)
102+
return @retry_on_error apicall(apictx, d)
131103
elseif (apicall = _api_function("createNamespaced$O")) !== nothing
132-
return apicall(apictx, ctx.namespace, d)
104+
return @retry_on_error apicall(apictx, ctx.namespace, d)
133105
else
134106
throw(ArgumentError("No API functions could be located using :$O"))
135107
end
@@ -149,10 +121,10 @@ function delete!(ctx::KuberContext, O::Symbol, name::String; apiversion::Union{S
149121
params = [apictx, name]
150122

151123
if (apicall = _api_function("delete$O")) !== nothing
152-
return apicall(params...; kwargs...)
124+
return @retry_on_error apicall(params...; kwargs...)
153125
elseif (apicall = _api_function("deleteNamespaced$O")) !== nothing
154126
push!(params, ctx.namespace)
155-
return apicall(params...; kwargs...)
127+
return @retry_on_error apicall(params...; kwargs...)
156128
else
157129
throw(ArgumentError("No API functions could be located using :$O"))
158130
end
@@ -171,9 +143,9 @@ function update!(ctx::KuberContext, O::Symbol, name::String, patch, patch_type;
171143
apictx = _get_apictx(ctx, O, apiversion)
172144

173145
if (apicall = _api_function("patch$O")) !== nothing
174-
return apicall(apictx, name, patch; _mediaType=patch_type)
146+
return @retry_on_error apicall(apictx, name, patch; _mediaType=patch_type)
175147
elseif (apicall = _api_function("patchNamespaced$O")) !== nothing
176-
return apicall(apictx, name, ctx.namespace, patch; _mediaType=patch_type)
148+
return @retry_on_error apicall(apictx, name, ctx.namespace, patch; _mediaType=patch_type)
177149
else
178150
throw(ArgumentError("No API functions could be located using :$O"))
179151
end

0 commit comments

Comments
 (0)