I have a post-hook function that receives some data for itself, reference to another function and arguments for that arbitrary function in ...
. This function does some post-processing, after referenced function returns. For simplicity let's just note time:
function passthrough(tag, func, ...)
metric1[tag] = os.time()
func(...)
metric2[tag] = os.time()
end
Since I need to postprocess, I can't immediately return func(...)
and I don't know in advance how many returns there will be. How can I passthrough those returns after I'm done with post-processing?
So far I can think only of packing call in local results = { func(...) }
and then using return unpack(results)
or making a postprocessor factory that'd generate postprocessing closure with all necessary data as upvalues:
local function generate_postprocessor(tag)
return function(...)
metric2[tag] = os.time()
return ...
end
end
function passthrough2(tag, func, ...)
metric1[tag] = os.time()
return generate_postprocessor(tag)(func(...))
end
However, both those approaches would introduce some overhead that is undesirable, considering high amount of iterations and real-time nature of application. Is there anything simpler?
You don't need the closure. func
is called before calling your closure generator anyway. You just need a function that passes its arguments straight through to its return values to give you a hook point for your second tag:
function passthrough_return(tag, ...)
metric2[tag] = os.time()
return ...
end
function passthrough(tag, func, ...)
metric1[tag] = os.time()
return passthrough_return(tag, func(...))
end
You're still getting the overhead of an extra function call, but that's better than creating a closure or a table and far less than the overhead of your pre/post processing.
来源:https://stackoverflow.com/questions/11961442/post-hook-a-function-post-process-and-pass-through-all-returns