User:Void Singer/Saucer

From Second Life Wiki
Jump to navigation Jump to search

Saucer

What is it?


Saucer is an optional open source Extension to Teacup that helps prevent missing or bad pages from delaying webpage loads.

How does it work?


Once Saucer starts up, it advertises it's existence to available file sources, which can signal which pages they have available to serve. If it hears a request from the Teacup server, it checks to see if the requested page is already known to it, and if so, does nothing. If not, the page name is added to a queue and then Saucer waits a few seconds to see if anything responds to that request; if not, it sends a "404 Not Found" message to the server so that webpages waiting for it can know that the file isn't available and continue immediately. If a service does respond to the request within 2 seconds, with a "100 Continue", Saucer will not send a 404 message for that request. Additionally, any request that is filled via a "200 Success" message, will be added to it's list of known files.

Code

Saucer


  • Save to a MONO script named "Saucer v0.5" and place in the same prim as Teacup
/*( Saucer v0.5 )*/


/*//-- Request Handler variables --//*/
list    gLstPag;    //-- List of known pages
list    gLst404Tim; //-- 404 timeout
list    gLst404Key; //-- 404 request key
list    gLst404Pag; //-- 404 page name (used for discovery only)
integer gIntLnk;    //-- link number to save on function calls


default{
	state_entry(){
		gIntLnk = llGetLinkNumber();
		llMessageLinked( LINK_SET, 418, "Saucer Start", NULL_KEY );
	}
	
	link_message( integer vIntSrc, integer vIntDta, string vStrDta, key vKeyDta ){
		if (vKeyDta){ //-- server traffic?
			if (418 == vIntDta && gIntLnk == vIntSrc){ //-- server request? // next line: Ignore Known Pages
				if (!~vIntDta = llListFindList( gLstPag, [vStrDta = llList2String( llParseStringKeepNulls( vStrDta, ["?"], [] ), 0 )] )){
					gLst404Key += [vKeyDta]; //-- Pending 404 key (used to detect lazy page additions or Send 404s)
					gLst404Pag += [vStrDta]; //-- Pending 404 name (used for lazy Know Page additions)
					gLst404Tim += [llGetUnixTime() + 2]; //-- Timeout value: this actually amount to a ~2.25sec timeout
					if (gLst404Tim == [""]){ //-- Only start timer for first pending 404, avoids bumping the timer forward.
						llSetTimerEvent( 0.75 ); //-- Fast to deal with fast pages requests
					}
				} //-- Next Line: Check for unadvertised responses for pending 404s
			}else if (~vIntSrc = llListFindList( gLst404Key, [vKeyDta] )){
				if (200 == vIntDta){ //-- auto discovery of  unadvertised pages
					gLstPag += [llList2String( gLst404Pag, vIntSrc )];
				}
				gLst404Tim = llDeleteSubList( gLst404Tim, vIntSrc, vIntSrc );
				gLst404Key = llDeleteSubList( gLst404Key, vIntSrc, vIntSrc );
				gLst404Pag = llDeleteSubList( gLst404Pag, vIntSrc, vIntSrc );
			}
		}else if (601 == (1 | vIntDta) && NULL_KEY == (string)vKeyDta){
			if (1 & vIntDta){ //-- 601 = add file (if NOT found)
				if (!~vIntDta = llListFindList( gLstPag, [vStrDta] )){
					gLstPag += [vStrDta];
				}
			}else{ //-- 600 remove file (only if found, avoids wrong index)
				if (~vIntDta = llListFindList( gLstPag, [vStrDta] )){
					gLstPag = llDeleteSubList( gLstPag, vIntDta, vIntDta );
				}
			}
		}
	}
	
	timer(){ //-- handle pending 404s
		if (gLst404Tim != []){ //-- Pending 404s?
			while (llList2Integer( gLst404Tim, 0 ) < llGetUnixTime()){ //-- Timeouts expired?
				llMessageLinked( llGetLinkNumber(), 404, "404 Not Found", llList2Key( gLst404Key, 0 ) );
				gLst404Tim = llDeleteSubList( gLst404Tim, 0, 0 ); //-- Send 404, Remove pending
				gLst404Key = llDeleteSubList( gLst404Key, 0, 0 );
				gLst404Pag = llDeleteSubList( gLst404Pag, 0, 0 );
				if (gLst404Tim == []){ //-- Pending Queue empty?
					llSetTimerEvent( 0.0 );
					return; //-- Stop timer, & exit
				}
			}
		}else{ //-- No Pending 404s, stop timer
			llSetTimerEvent( 0.0 );
		}
	}
}
/*//--                           License Text                           --//*/
/*//  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
/*//    (C)2011 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/
Return to top

Protocol

Special Messages

Saucer accepts three special messages using the Teacup Protocols.

"File Removed"
llMessageLinked( LINK_SET, 600, "File Name", NULL_KEY ); //-- as called by another script
"File Added"
llMessageLinked( LINK_SET, 601, "File Name", NULL_KEY ); //-- as called by another script
"100 Continue"
llMessageLinked( LINK_SET, 100, "File Name", REQUEST_KEY ); //-- as called by another script

where "File Name" is the name of the file that the service is adding, removing, or serving. and REQUEST_KEY is the key of the request from the server for that file.

  • LINK_SET should be replaced with the server prim number when known to prevent spamming messages

Basic Functions

Upon startup, Saucer will advertise it's availability with "Saucer Start"

Services that take longer than 2 seconds to respond normally have two options to avoid their pages being timed out quickly

  1. Send a "File Added" message for each file name they service when they start, and when they receive the "Saucer Start" advertisement
    • File names added in this manner should be removed with "File Removed" when no longer available
    • "File Added" messages should be throttled to no more than a few per second, suggest adding a delay based on link number.
  2. Immediately send a "100 Continue" message for server requested file names, then send the requested file normally when available.
    • This method does not require removal unless sent with a "200 Success" code. Instead, use codes "201 Created", "202 Accepted", or "204 No Content"

other services that can respond quickly should send files with "200 Success" where applicable to prevent additional processing by Saucer. Otherwise they should use Option 1 above.

  • Any file sent with a "200 Success" code will be added to the known files list
Return to top

Notes

Compatible Servers, File Systems, and Extensions


  • Teacup - SIP front end
  • Red Tea - A very simple SIP back end File Service for a starting point.
  • Region Stats - A single page Extension that gets live data from the region and refreshes every minute
  • Tea Strainer - Optional Troubleshooting Monitor for checking messages being sent and received.

Known Bugs


  • Current version responds to any unknown code in the proper format as if it were a "100 Continue".
    • This may be cleaned up in a future revision, Do not rely on this behavior
  • Not really a bug, but inefficient... must have one copy for each server
    • probably needs revised to save the server source too so that it can handle multiple Teacups

Requested Feature Upgrades


  • Got a feature request? add it here

Change Log / Old Versions


Most Recent Changes are at the top, old version links below.

  • Code will be considered stable when it reaches v1.0
  • Saucer v0.5
    • Update to match version number on Teacup, transparent tweaks and page formatting.
  • Saucer v0.3.1
    • Separated from The Teacup Server, and Messaging Protocol tweaked
  • Saucer v0.3
    • Initial Public Release
Return to top

Questions or Comments?

Feel free to leave me a note on the discussion page.