Friday, December 22, 2006

Updated Ajax RSS Web Part

I've updated my Ajax RSS Web Part to include a fix. The previous version would correctly present an error if the URL provided for the RSS feed did not exist or could not be accessed. Unfortunately, if the remote server did exist but was too slow to respond, the Web Part would wait forever for the response.

I ran into this recently when the Charlotte.com web server seemed to stop responding. If I tried to load their web page in Internet Explorer, it would just continue loading and never error out. As a result, our Sharepoint home page also appeared to lock up.

If a web part page ever locks up on you, you can use the "magic" web part maintenance URL to disable any rogue web parts (the URL is 2 lines below):

http://servername/_layouts/1033/spcontnt.aspx?PageView=Shared&
url=%2fdefault.aspx%3fMode%3dEdit%26PageView%3dShared

This URL allows you to delete or close any web part in case you cannot access the web part page directly.

In any case, I added the following code to launch the RSSFeed.Read() call in a separate thread and time it out when required. The code will wait for 9 seconds for the remote web server to respond before it will abort the operation.

'Create a separate thread to load the RSS Feed so we can
'cancel if it is taking too long
Dim threadSuccessful As Boolean = True
Dim thread As New Thread(New ThreadStart(AddressOf GetRSSObject))
Dim timeStart As DateTime = Now
thread.IsBackground = True
thread.Start()
Do
'If the thread finishes, then exit loop
If Not thread.IsAlive() Then
Exit Do
End If

'wait for 100 milliseconds so we don't tie up the CPU
thread.Sleep(100)

If DateDiff(DateInterval.Second, timeStart, Now) > 10 Then
'If it has been 10 seconds, stop waiting
thread.Abort()
threadSuccessful = False
End If
Loop

If threadSuccessful Then
Dim timeToLive As Int32 = GetRSSFeedTTL()

'Add the feed to the cache of the web server. The cache entry should
'expire when the next revision of the news feed is ready.
context.Cache.Add(_rssURL, newsFeed, Nothing, _
newsFeed.LastModified.AddMinutes(timeToLive), _
TimeSpan.Zero, Web.Caching.CacheItemPriority.Normal, Nothing)
Else
errorDetail = "Timeout waiting for the <a href=""" & _rssURL & _
""">specified news feed</a> to respond."
End If

I then moved the RSS code into its own sub:

'-----------------------------------------------------------------
'Code to populate the newsFeed object...called as a thread
'-----------------------------------------------------------------
Sub GetRSSObject()
newsFeed = RssFeed.Read(_rssURL)
End Sub

Please note that once an error occurs the Ajax functions are disabled. Therefore, if you see the timeout error message once, the web part will not keep retrying in the background unless you refresh the whole page.

You can dowload the updated code and compiled binary from the main post. If you've already installed it previously, just replace the AjaxRSS.dll with this updated version.

No comments: