View Full Version : Employing server resiliency for downloads as well
Ken Gartner
03-08-2005, 02:21 PM
The Update.exe client will march through the ordered list of update servers until it comes to one that works fine. It is usually not important which one was selected since all of your update.tu* files are replicated.
However, I want to also replicate my file downloads to work with the code snippet shown below. In this case I need to know the HTTP URL base of the host used to download the update server files, since I will have already replicated my patch files there as well. I have not found a way to learn this information on the fly, so I suppose I have to hardwire the TrueUpdate.GetUpdateServerList() indexes to the hosts URL base. Can anyone suggest a programmatic way to learn the host we connected to so I can set my _DOWNLOAD_URLBASE variable below?
local RemoteFileURL = _DOWNLOAD_URLBASE.."/files/config.xml";
HTTP.Download(RemoteFileURL, LocalFileName);
Thanks for the help.
-Ken Gartner
Lorne
03-08-2005, 04:03 PM
The Update.exe client will march through the ordered list of update servers until it comes to one that works fine.
That functionality is actually scripted. For example, if you're using the Download Server Script screen to download the server files, the script that runs through the TrueUpdate servers is on that screen's On Start tab.
The index of the table element that contains the successful server's information is stored in screen_globals.CurrentServerIndex, which is valid in that screen's On Finish event.
The index references the tableTrueUpdateServers table, which is local to the On Start event by default.
You can easily modify the On Start event to make tableTrueUpdateServers a global object, and store the index in a more permanent variable than screen_globals.CurrentServerIndex too. Just replace the default script with the following script on that screen's On Start event:
-- These actions are performed when the screen is shown.
-- Set up a table for this screen's global variables
-- so we don't accidentally modify any global variables that are used elsewhere
screen_globals = {};
-- Whether the Cancel button has been clicked.
-- We'll set this to true when the user clicks the Cancel button
-- to tell the GetServerFileCallback function to stop the download
screen_globals.Cancelled = false;
-- Whether the server configuration files have been downloaded.
-- We'll set this to true once the download is successful
-- so we can act accordingly in the On Finish event
screen_globals.GotServerFiles = false;
-- Keep track of which TrueUpdate Server we're downloading from
screen_globals.CurrentServerIndex = 0;
-- Initialize the progress bar
DlgProgressBar.SetRange(CTRL_PROGRESS_BAR_01, 0, 100);
DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, 0);
-----------------------
-- Callback Functions
-----------------------
-- Function: GetServerFileCallback
-- Purpose: Displays the progress and status of
-- a TrueUpdate.GetServerFile action
-- Returns: true - if the GetServerFile action should continue
-- false - if the GetServerFile action should abort
function GetServerFileCallback(BytesDownloaded, FileSize, TransferRate, SecondsLeft, EstimatedTimeRemaining, ServerStatusMessage, tableClientUpdateInfo)
-- Did the user click Cancel?
if(screen_globals.Cancelled) then
-- Tell the GetServerFile action to abort
return false;
end
-- Set a default value for the "Downloading:" message
-- (by default we start out downloading update information...)
local Downloading = TrueUpdate.GetLocalizedString("MSG_UPDATE_INFORMATION");
-- Set appropriate messages if we're updating the TrueUpdate Client
if(tableClientUpdateInfo) then
-- What part of the Client are we updating?
if(tableClientUpdateInfo.UpdateType == 0) then
Downloading = TrueUpdate.GetLocalizedString("MSG_UPDATE_EXECUTABLE");
else
Downloading = TrueUpdate.GetLocalizedString("MSG_UPDATE_DATA");
end
end
-- Reset the progress bar if we've started downloading something different
if((screen_globals.Downloading == nil) or (Downloading ~= screen_globals.Downloading)) then
DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, 0);
-- Keep track of what we're downloading so we can reset the
-- progress bar when we start downloading something else.
screen_globals.Downloading = Downloading;
end
-- Update the status text to show what we're downloading
DlgStaticText.SetProperties(CTRL_STATICTEXT_LABEL_ 01, {Text=TrueUpdate.GetLocalizedString("MSG_DOWNLOADING")..": "..Downloading.." "..TrueUpdate.GetLocalizedString("MSG_FROM").." "..TrueUpdate.GetLocalizedString("MSG_SERVER_NUMBER").." "..screen_globals.CurrentServerIndex});
-- Calculate the percentage that has been downloaded so far
local PercentComplete = 0;
if(FileSize > 0) then
PercentComplete = (BytesDownloaded/FileSize) * 100;
end
-- Update the progress bar
DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, PercentComplete);
-- Update the status text
if(ServerStatusMessage == "") then
-- We're downloading...
-- Shorten the TransferRate to 2 decimal places
local TransferRateFormatted = string.format("%.2f", TransferRate);
-- Display the elapsed time or time remaining
-- and the current transfer rate
if(FileSize > 0) then
-- We know the size of the file we're downloading
-- so use the estimated time remaining
local StatusText = TrueUpdate.GetLocalizedString("MSG_ESTIMATED_TIME_LEFT")..": "..EstimatedTimeRemaining.." - "..TrueUpdate.GetLocalizedString("MSG_TRANSFER_RATE")..": "..TransferRateFormatted.." "..TrueUpdate.GetLocalizedString("MSG_KB_PER_SEC");
DlgStaticText.SetProperties(CTRL_STATICTEXT_LABEL_ 02, {Text=StatusText});
else
-- We don't know the size of the file we're downloading
-- so calculate the elapsed time
local SecondsElapsed = os.time() - screen_globals.TimeStarted;
-- from _TU20_Global_Functions.lua:
-- Translate the elapsed download time
-- into a formatted string ("mm:ss" or "hh:mm:ss")
local TimeElapsed = g_GetFormattedTime(SecondsElapsed);
local StatusText = TrueUpdate.GetLocalizedString("MSG_ELAPSED_TIME")..": "..TimeElapsed.." - "..TrueUpdate.GetLocalizedString("MSG_TRANSFER_RATE")..": "..TransferRateFormatted.." "..TrueUpdate.GetLocalizedString("MSG_KB_PER_SEC");
DlgStaticText.SetProperties(CTRL_STATICTEXT_LABEL_ 02, {Text=StatusText});
end
else
-- We're waiting for the server...
-- Show the current status message
DlgStaticText.SetProperties(CTRL_STATICTEXT_LABEL_ 02, {Text=ServerStatusMessage});
end
-- Tell the GetServerFile action to continue
return true;
end
------------------------------
-- Download the server files
------------------------------
-- Get the list of TrueUpdate Server locations
tableTrueUpdateServers = TrueUpdate.GetUpdateServerList();
if(tableTrueUpdateServers) then
-- Get the current date/time in seconds
-- (we'll use this as a reference point
-- to calculate the elapsed time)
screen_globals.TimeStarted = os.time();
-- Go through the list of TrueUpdate Server locations
-- until we find one where we can successfully download
-- the required configuration files
for index, ServerName in tableTrueUpdateServers do
screen_globals.CurrentServerIndex = index;
-- Attempt to download the server configuration files
-- Note: this action will download the Server Script
-- and may also update the TrueUpdate Client
-- if required
screen_globals.GotServerFiles = TrueUpdate.GetServerFile(ServerName, true, GetServerFileCallback);
-- Break out of this loop if we succeeded
if(screen_globals.GotServerFiles) then
UpdateServerIndex = screen_globals.CurrentServerIndex;
break;
end
end
end
I've highlighted the two lines that I added/modified in blue.
Ken Gartner
03-09-2005, 05:18 AM
Lorne, thanks for the detailed reply. There is still a gap. Knowing the defined server's index does not directly provide me with the info I need for the HTTP.Download call.
For example, I have defined the following list of TrueUpdate Servers:
Name Type Location
===========================================
HTTP Server 01 HTTP http://www.myhost.com/softupdates/A
HTTP Server 02 HTTP http://www.althost.com/test/updates/root
HTTP Server 03 HTTP http://www.internalmachine.com/dev/updates
As the result of knowing the table index, my program learns the following
[03/08/2005 15:05:08] Product update information has been found at HTTP Server 01
However, knowing 'HTTP Server 01', I cannot seem to find any programmatic data structure or API call which would return 'http://www.myhost.com/softupdates/A", which I would like to use as a base URL for subsequent HTTP downloads. Other than building such a table myself -- this would be fragile code that would be hard to maintain over time -- is there programmatic access to the 'Type' and 'Location' fields of tableTrueUpdateServers.
Thanks.
-Ken
vBulletin® v3.7.3, Copyright ©2000-2009, Jelsoft Enterprises Ltd.