I’ve been experiencing some conflicts when juggling multiple simultaneous http requests. This is probably due to my misunderstanding of handling references in a context. I have some example code below that will run as is.
However, if I query /first followed quickly by /second, I get { result=second } and then (after 10 seconds) an error as the agent tries to send the same HTTP response twice.
I had thought that by binding the context of function(httpReq,httpResp)… to each of the calls to onResult, I would not have to explicitly retain the objects httpReq and httpResp. But it seems that once the second http request arrives, it shares the same references as the first. What is the cleanest way for me to handle this?
Is it better for me to put onResult outside of the http.onrequest() handler and pass it references to httpReq and httpResp?
e.g. function(){ onResult({ result=“x” },httpReq,httpResp) }
It is what I use. What you tried to attempt- sorry it is above my skill to answer it. To me the presence of a function definition ‘onResult’ inside inside the http handler looks improper but this could just be because I am not an expert.
You’re right, that does look wrong and might be a bug. Both on the agent and the device, the following simplified code:
`function f(req, res) {
function done® { server.log(res.a + “,” + r.b); }
switch (res.a) {
case 0: imp.wakeup(0.0, function() { done({b=0}); }); break;
case 1: imp.wakeup(1.0, function() { done({b=1}); }); break;
}
}
f(1,{a=1});
f(0,{a=0});`
prints “0,0” and “0,1” rather than the “0,0” and “1,1” that I’d kind-of expect. Surely the closure formed for done() should refer to the “res” in the current invocation of “f”. (You don’t need the bindenv, because “res” (“httpResp” in your code) is a local of an outer function, not a member of any context object.)
The workaround, of passing httpReq and httpResp to onResult directly, should work fine.
(Naturally I spot the problem just after posting saying that I can’t spot the problem.)
The statement “function onResult(…)” is shorthand for “onResult <- function(…)”: in other words, it stores the closure representing “onResult” in the context object. In your case, that’s the global object. So the second call to the handler overwrites that closure with the new closure.
What you want instead is: local function onResult(response){
which will do the Right Thing. This isn’t a bug, it’s just Squirrel’s function declaration syntax being confusing.