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