Export (0) Print
Expand All
4 out of 8 rated this helpful - Rate this topic

Strategies for Writing Startup Tasks that can run Multiple Times

Updated: November 13, 2013

In Windows Azure, startup tasks are executed when you first start your role, when your role reboots, and when your role recycles. Because startup tasks execute on role recycles (which do not include a reboot), startup tasks must be written so that they can run more than once between reboots.

Roles Can Recycle Without Rebooting

Roles can recycle for a few reasons. Roles can recycle if WaWebHost.exe or WaWorkerHost.exe crash while hosting your application. Also, if you stop and then start your deployment, then the role will recycle.

Because of these reasons, startup tasks must work even if they are run more than once between reboots. This is important because if a simple task ends with a non-zero errorlevel (or exit code), subsequent simple roles and the role itself will not start. A foreground task can also be problematic because the role will run while the foreground task runs, so if the foreground task hangs the role will not recycle.

Strategies

There are a few strategies for writing a startup task that will work, even when the tasks would generate errors if run more than once.

Run through the startup task

If the errors can be safely ignored when running a startup task multiple times, or if the startup task does not generate errors, there is no need to do anything special with the startup task. Of course, you should always write a log of the startup activities for debugging later.

Recognize when a task was already performed

If a task only needs to be performed once, or if a task can or should only be performed once, the task can create a small file in the %RoleRoot% directory to indicate success. The startup batch file can then check for the existence of this file and skip that step or exit the batch file entirely.

The following example creates the file App1Install_Success.txt when the application installs without error. If the App1Install_Success.txt file already exists, then the batch file skips the install process:

REM   This startup batch file installs the fictitious program Application 1

REM   If App1Install_Success.txt exists, then Application 1 is already installed.
IF EXIST "%RoleRoot%\App1Install_Success.txt" (
ECHO Application 1 is already installed. Exiting. >> "%TEMP%\StartupLog.txt" 2>&1
GOTO AfterApp1Install
)

REM   Install Application 1.
ECHO Installing Application 1 >> "%TEMP%\StartupLog.txt" 2>&1
"%PathToApp1Install%\setup.exe" >> "%TEMP%\StartupLog.txt" 2>&1

IF %ERRORLEVEL% EQU 0 (
  REM   The application installed without error. Create a file to indicate that the application 
  REM   does not need to be installed again.

  ECHO This line will create a file to indicate that Application 1 installed correctly. > "%RoleRoot%\App1Install_Success.txt"
) ELSE (
  REM   An error occurred. Log the error and exit with the error code.

  DATE /T >> "%TEMP%\StartupLog.txt" 2>&1
  TIME /T >> "%TEMP%\StartupLog.txt" 2>&1
  ECHO  An error occurred installing Application 1. Errorlevel = %ERRORLEVEL%. >> "%TEMP%\StartupLog.txt" 2>&1

  EXIT %ERRORLEVEL%
)

:AfterApp1Install

REM   Exit normally.
EXIT /B 0

Perform error checking and error handling

Another strategy is to check the errorlevel after each step in the startup task. Expected errors are handled, and the batch file continues. Unexpected errors are logged and the batch file exits.

The following example adds a section to the IIS Web.config file using AppCmd.exe. If the section already exists, then AppCmd.exe displays an error and exits with an errorlevel of 183. This is expected when the batch file is run more than once, so the errorlevel is set back to zero using the verify.exe command (using verify.exe with no parameters will display a simple message, then set the errorlevel to zero). If the errorlevel is any other non-zero value (such as 5, for access denied), then the batch file logs the error and exits.

REM   *** Add a compression section to the Web.config file. ***
%windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1

REM   ERRORLEVEL 183 occurs when trying to add a section that already exists. This error is expected if this
REM   batch file were executed twice. This can occur and must be accounted for in a Windows Azure startup
REM   task. To handle this situation, set the ERRORLEVEL to zero by using the Verify command. The Verify
REM   command will safely set the ERRORLEVEL to zero.
IF %ERRORLEVEL% EQU 183 DO VERIFY > NUL

REM   If the ERRORLEVEL is not zero at this point, some other error occurred.
IF %ERRORLEVEL% NEQ 0 (
   ECHO Error adding a compression section to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
   GOTO ErrorExit
)

REM   *** Add compression for json. ***
%windir%\system32\inetsrv\appcmd set config  -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1
IF %ERRORLEVEL% EQU 183 VERIFY > NUL
IF %ERRORLEVEL% NEQ 0 (
   ECHO Error adding the JSON compression type to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
   GOTO ErrorExit
)

REM   *** Exit batch file. ***
EXIT /b 0

REM   *** Log error and exit ***
:ErrorExit
REM   Report the date, time, and ERRORLEVEL of the error.
DATE /T >> "%TEMP%\StartupLog.txt" 2>&1
TIME /T >> "%TEMP%\StartupLog.txt" 2>&1
ECHO An error occurred during startup. ERRORLEVEL = %ERRORLEVEL% >> "%TEMP%\StartupLog.txt" 2>&1
EXIT %ERRORLEVEL%

See Also

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.