lubURL nuances
Jeffrey Massung
massung at gmail.com
Thu Mar 11 09:32:31 EST 2010
Richard,
I've spent quite a bit of time figuring out #1 and #2 of your question list. I have a couple... URL intensive apps, and I used to get the "previous request" error all the time. Here's what I've learned through experimentation.
1. Blocking...
The PUT URL command is only blocking _within the context of the current handler_. You can think of it as if it was written like so in code:
get url "http://..." WITH MESSAGES
Meaning that the current handler stops what it's doing waiting for the HTTP fetch to complete, but you can still resize the window, watch GIFs animate, and even click buttons.
2. Previous request errors...
You'll get these because of the behavior that PUT URL has (the fact that it allows messages to keep being processed). This behavior is actually a good thing, but means you need to be careful.
For example, if you have a button that does a PUT URL on mouseUp, you can click that button many times really fast, and all of them will execute and yield in their handlers once they get to the PUT URL command. The first one will be in the process of fetching the URL when the second one hits the same line of code and trip the "previous request" error.
---
Now on to solutions...
I've found 2 solutions to this problem that appear to work best.
1. Use LOAD URL exclusively whenever you can. Sadly, this approach fails if you have to do any POST commands, because you can't perform a POST with a callback; it always acts like a PUT URL. This means the POST can fail. But, when it does fail, it fails instantly, you know it failed, and you can try again immediately.
2. Don't trust the LOAD URL message queue that Rev comes with built-in. Sadly, while their message queue for loading URLs is just fine, it doesn't let you inspect it (you can't tell if a URL is currently being loaded, what it is, or what the status of it is). Instead, roll your own. This also has the nice ability of being able to debug easily:
global gHttpCmdQ
on postHttpCmd pAction, pURL, pTarget, pCallback
get gHttpCmdQ is empty
## insert the command onto the queue to be processed later
put pAction & tab & pURL & tab & pTarget & tab & pCallback & cr after gHttpCmdQ
## if there were no commands on the queue, process this new one now
if it is true then
processHttpCmds
end if
end postHttpCmd
on processHttpCmds
local tAction
local tURL
local tTarget
local tCallback
get the first line of gHttpCmdQ
if it is empty then
exit processHttpCmds
end if
## pop the command off the queue
delete the first line of gHttpCmdQ
set the itemDelimiter to tab
put item 1 of it into tAction
put item 2 of it into tURL
put item 3 of it into tTarget
put item 5 of it into tCallback
switch tAction
case "GET"
get URL tURL
break
case "POST"
post ...
break
## more command types here
end switch
if the result is not empty then
dispatch tCallback to tTarget with "error" , the result
else
dispatch tCallback to tTarget with "cached" , it
end if
## continue processing messages from the queue
send "processHttpCmds" to me in 0 seconds
end processHttpCmds
---
Anyway, I use something very similar in my apps and I have yet to run into any problems. YMMV, though.
HTH,
Jeff M.
On Mar 11, 2010, at 7:23 AM, Richard Gaskin wrote:
> While working with Dan Friedman to diagnose some FTP issues, he came up with some questions I couldn't answer so I'm bringing them to y'all to see what we can find:
>
> 1. Is "put url..." a blocking command?
> I believe it's supposed to be, but find I can sometime do other
> things while it's running, including submitting subsequent
> "put url..." commands.
>
> 2. In such a circumstance, the second attempt to "put url..."
> meets with an error, "Previous request not completed." I've
> found that once that error hits the original request sometimes
> runs into trouble, requiring me to use libUrlResetAll and
> try again. Is there a more graceful way to handle that error?
More information about the use-livecode
mailing list