//private static readonly string FilePath = string.Format("{0}{1}", RoleEnvironment.GetLocalResource(LocalStorage.StorageName).RootPath, LocalStorage.LockName); //private readonly CloudBlockBlob _blockBlob; //public MvcApplication() //{ // var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("Node.Storage.ConnectionString")); // var blobClient = storageAccount.CreateCloudBlobClient(); // var container = blobClient.GetContainerReference("node"); // container.CreateIfNotExists(); // _blockBlob = container.GetBlockBlobReference(string.Format("offline.{0}.lock", RoleEnvironment.CurrentRoleInstance.Id.GetHash())); //} protected void Application_Start() { Trace.TraceInformation("Application_Start"); // TODO: [Optimization] ServicePointManager.DefaultConnectionLimit = 12; // Initalize ProtoBuf ProtoBufConfig.Init(); // Register Filters FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); // Register Routes RouteConfig.RegisterRoutes(RouteTable.Routes); // Get Destination Data & Populate Cache try { #if DEBUG SetupConfig.Init(HttpContext.Current); #else SetupConfig.Init(); #endif } catch (Exception ex) { Trace.TraceError("SetupConfig Exception"); // This will catch a misconfigured Worker Endpoint and inform of Faulted ServiceBusSingleton.Instance.SendCommandAsync(new Command { Type = Commands.Faulted }).Wait(); return; } #region ServiceBusSingleton // Init Updates callback ServiceBusSingleton.Instance.OnUpdateMessage(message => { try { // Process message from subscription var update = message.GetBody <Update>(_xpsUpdate); if (update.Destination != null) { // TODO: Clean this foreach (var flight in MemoryCache.Default) { var item = flight.Value as WeightedSelector <DestinationsUpdate>; if (item == null) { continue; } foreach (var dest in item.ListByWeightAscending().Where(a => a.Value.Destination == update.Destination.ToString())) { item.Remove(dest); item.Add(new DestinationsUpdate { Flight = update.Flight != null ? update.Flight.ToString() : dest.Value.Flight, Destination = update.Destination.ToString(), Url = update.Url }, 1); } } } else if (update.Flight != null) { var flights = DestinationsCache.Get(update.Flight); // TODO: There currently is no way to select and update a single entry in WeightedSelector foreach (var flight in flights.ListByWeightAscending().Where(flight => flight.Value.Destination == update.Destination.ToString())) { flights.Remove(flight); flights.Add(new DestinationsUpdate { Flight = update.Flight.ToString(), Destination = update.Destination != null ? update.Destination.ToString() : flight.Value.Destination, Url = update.Url }, 1); } } // ReSharper disable RedundantIfElseBlock else { // TODO: If the entry isn't in the cache then what? Request fresh data from Worker? } // ReSharper restore RedundantIfElseBlock // Remove message from subscription message.Complete(); } catch (Exception) { // TODO: Log error & dead letter message // Indicates a problem, unlock message in subscription message.Abandon(); } }); // Inform Worker its online (used later for monitoring Nodes) // TODO: Add Instance ID ServiceBusSingleton.Instance.SendCommandAsync(new Command { Type = Commands.Online }).Wait(); #endregion // Set Node online //if (!_blockBlob.DeleteIfExists()) //{ // throw new NotImplementedException(); //} //File.Delete(FilePath); }
public async Task <ActionResult> Index() { // Flight var flight = Request.QueryString.Get(QueryStrings.FlightId); if (string.IsNullOrWhiteSpace(flight)) { // TODO: Log the error and redirect to a default catch all address (value should be setup in Frontend config) throw new NotImplementedException("'flight' is NULL"); } // User ID var userId = Request.Cookies.Get(Cookies.UserId); var uid = userId != null ? userId.Value : Guid.NewGuid().ToString(); // Destination List var destinations = DestinationsCache.Get(flight); if (destinations == null) { // TODO: Log the error and request update for Flight ID throw new NotImplementedException("'destinations' is NULL"); } // Select Destination (Weighted) var destination = destinations.Select(); // NOTE: .NET v4.5.2 (currently not supported on Azure) // TODO: There needs to be a fallback if the node can't connect to the Service Bus (eg. MSMQ) //HostingEnvironment.QueueBackgroundWorkItem(ct => ServiceBusSingleton.Instance.SendEventAsync(new Event //{ // Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), // UserId = uid, // UserAgent = Request.UserAgent, // UserHostAddress = Request.UserHostAddress, // UserProxyAddress = Request.Headers.Get("X-FORWARDED-FOR"), // Flight = flight, // Destination = destination.Destination //})); // TODO: There needs to be a fallback if the node can't connect to the Service Bus (eg. MSMQ) await ServiceBusSingleton.Instance.SendEventAsync(new Event { Type = EventType.AdvertClick, Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), UserId = uid, UserAgent = Request.UserAgent, UserLanguage = Request.Headers.Get("Accept-Language"), UserHostAddress = Request.UserHostAddress, UserProxyAddress = Request.Headers.Get("X-FORWARDED-FOR"), Referer = Request.UrlReferrer == null ? null : Request.UrlReferrer.AbsoluteUri, Flight = flight, Destination = destination.Destination }).ConfigureAwait(true); // TODO: Fix this for cross domain issues Response.AppendCookie(new HttpCookie(Cookies.UserId, uid) { //Domain = "", Expires = DateTime.UtcNow.AddYears(2) }); #if DEBUG || RELEASE_DEMO var debugMode = Request.QueryString.Get(QueryStrings.DebugMode); if (!string.IsNullOrWhiteSpace(debugMode)) { return(View(destination)); } #endif // Redirect to URL return(Redirect(destination.Url)); }