Skip to content

Instantly share code, notes, and snippets.

@pofallon
Created December 5, 2010 04:40
Show Gist options
  • Save pofallon/728804 to your computer and use it in GitHub Desktop.
Save pofallon/728804 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using NLog;
using NLog.Targets;
using NLog.Config;
/* This code was inspired by a couple of posts/projects:
* http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/
* http://code.msdn.microsoft.com/winazuretomcat
*/
namespace NodeRunner
{
public class WorkerRole : RoleEntryPoint
{
private Process _nodeProcess;
private Logger logger;
private void ConfigureLogging()
{
LocalResource logResource = RoleEnvironment.GetLocalResource("LogStorage");
//Get the default initial configuration for Windows Azure Diagnostics
DiagnosticMonitorConfiguration diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
DirectoryConfiguration directoryConfiguration = new DirectoryConfiguration();
directoryConfiguration.Container = "wad-node-container";
directoryConfiguration.DirectoryQuotaInMB = logResource.MaximumSizeInMegabytes;
directoryConfiguration.Path = logResource.RootPath;
diagConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.Directories.BufferQuotaInMB = 512;
diagConfig.Directories.DataSources.Add(directoryConfiguration);
// *** NLog Configuration ***
LoggingConfiguration config = new LoggingConfiguration();
FileTarget fileTarget = new FileTarget();
config.AddTarget("file", fileTarget);
fileTarget.FileName = logResource.RootPath + "NodeRunner-log.txt";
LoggingRule rule1 = new LoggingRule("*", NLog.LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule1);
LogManager.Configuration = config;
logger = LogManager.GetLogger("NodeRunner");
//Start the diagnostic monitor with this updated configuration.
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diagConfig);
// DiagnosticMonitor.Start("StorageClientAccount", diagConfig);
}
private void DeployNode()
{
string nodeSource = Environment.GetEnvironmentVariable("RoleRoot") + @"\approot\nodejs";
string nodeDest = RoleEnvironment.GetLocalResource("NodeStorage").RootPath;
logger.Info("Deploying node.js from " + nodeSource + " to " + nodeDest);
CopyFiles(nodeSource, nodeDest);
}
private void DeployCode()
{
string codeSource = Environment.GetEnvironmentVariable("RoleRoot") + @"\approot\code";
string codeDest = RoleEnvironment.GetLocalResource("NodeStorage").RootPath;
logger.Info("Deploying source from " + codeSource + " to " + codeDest);
CopyFiles(codeSource, codeDest);
}
private void CopyFiles(string theSrc, string theDest)
{
Process p = new Process();
StreamReader sr;
try
{
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
string newDest = theDest.Substring(0, theDest.Length - 1);
p.StartInfo.FileName = "robocopy";
p.StartInfo.Arguments = String.Format("\"{0}\" {1} /E /NP", theSrc, newDest);
p.EnableRaisingEvents = false;
p.Start();
sr = p.StandardOutput;
logger.Debug(sr.ReadToEnd());
p.WaitForExit();
p.Close();
}
catch (Exception e)
{
logger.Error(e.Message);
}
}
private void StartNode()
{
// Startup _nodeProcess
string theIp = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["NodeEndpoint"].IPEndpoint.Address.ToString();
string thePort = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["NodeEndpoint"].IPEndpoint.Port.ToString();
string thePath = RoleEnvironment.GetLocalResource("NodeStorage").RootPath;
_nodeProcess = new Process();
try
{
_nodeProcess.StartInfo.UseShellExecute = false;
_nodeProcess.StartInfo.RedirectStandardOutput = false;
_nodeProcess.StartInfo.FileName = thePath + @"node.exe";
_nodeProcess.StartInfo.WorkingDirectory = thePath;
_nodeProcess.StartInfo.Arguments = String.Format("index.js {0} {1}", thePort, theIp);
_nodeProcess.EnableRaisingEvents = false;
logger.Info("Starting Node process on IP " + theIp + ", Port " + thePort);
_nodeProcess.Start();
}
catch (Exception e)
{
logger.Error(e.Message);
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
ConfigureLogging();
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
RoleEnvironment.Changing += RoleEnvironmentChanging;
DeployNode();
DeployCode();
StartNode();
return base.OnStart();
}
public override void OnStop()
{
_nodeProcess.Close();
base.OnStop();
}
private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
// If a configuration setting is changing
if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
{
// Set e.Cancel to true to restart this role instance
e.Cancel = true;
}
}
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
logger.Info("NodeRunner entry point called");
while (true)
{
Thread.Sleep(10000);
Trace.TraceInformation("Working...");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment