public WebRoleData() { GenUtils.LogMsg("info", String.Format("WebRoleData: {0}, {1}, {2}, {3}", procname, procid, domain_name, thread_id), null); MakeWhereAndWhatAndRegionIdLists(); var ids = Metadata.LoadHubIdsFromAzureTable(); Parallel.ForEach(ids, id => //foreach (var id in ids) { GenUtils.LogMsg("info", "GatherWebRoleData: readying: " + id, null); var cr = Utils.AcquireRenderer(id); lock (this.renderers) { this.renderers.Add(id, cr); } lock (this.ready_ids) { this.ready_ids.Add(id); } }); //} // this pipe-delimited string defines allowed IDs in the /services/ID/... URL pattern this.str_ready_ids = String.Join("|", this.ready_ids.ToArray()); GenUtils.LogMsg("info", "GatherWebRoleData: str_ready_ids: " + this.str_ready_ids, null); }
public void GeneralAdmin(object o, ElapsedEventArgs args) { try { GenUtils.PriorityLogMsg("status", "GeneralAdmin", null); Utils.MakeWhereSummary(); // refresh http://elmcity.blob.core.windows.net/admin/where_summary.html Utils.MakeWhatSummary(); // refresh http://elmcity.blob.core.windows.net/admin/what_summary.html var ids = Metadata.LoadWhatWhereIdsFromAzureTable(); Parallel.ForEach(source: ids, body: (id) => { var calinfo = Utils.AcquireCalinfo(id); Utils.SaveIcalPerFeedLocations(calinfo, settings); }); } catch (Exception e) { GenUtils.LogMsg("exception", "GeneralAdmin", e.Message + e.StackTrace); } //Utils.MakeFeaturedHubs(); // idle for now }
private static string CallSearchApi(Uri search_url) { var delay = 2; try { delay = Convert.ToInt32(settings["search_engine_api_delay_secs"]); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CallSearchApi", e.Message + e.StackTrace); } Utils.Wait(delay); var r = HttpUtils.FetchUrl(search_url); if (r.status != HttpStatusCode.OK) { GenUtils.LogMsg("warning", "CallSearchApi" + r.status.ToString(), search_url.ToString()); return(null); } else { return(r.DataAsString()); } }
public static WebRoleData MakeWebRoleData() { WebRoleData wrd = null; try // create WebRoleData structure and store as blob, available to webrole on next _reload { var sw = new Stopwatch(); sw.Start(); wrd = new WebRoleData(); sw.Stop(); GenUtils.LogMsg("info", "new wrd: " + sw.Elapsed.ToString(), null); var info = String.Format("new wrd: where_ids: {0}, what_ids: {1}, region_ids {2}", wrd.where_ids.Count, wrd.what_ids.Count, wrd.region_ids.Count); GenUtils.LogMsg("info", info, null); GenUtils.LogMsg("info", "new wrd: " + wrd.str_ready_ids, null); sw.Start(); if (wrd.IsConsistent()) { SaveWrd(wrd); } else { GenUtils.PriorityLogMsg("warning", "MakeWebRoleData: inconsistent", null); wrd = GetWrd(); // fall back to last known good } sw.Stop(); GenUtils.LogMsg("info", "save wrd: " + sw.Elapsed.ToString(), null); } catch (Exception e3) { GenUtils.PriorityLogMsg("exception", "MakeWebRoleData: creating wrd", e3.Message); } return(wrd); }
public static void SaveRegionStats(string region) { GenUtils.LogMsg("status", "SaveRegionStats: " + region, null); var ids = Utils.GetIdsForRegion(region); var region_report = new StringBuilder(); var chunks = new Dictionary<string, string>(); Parallel.ForEach(source: ids, body: (id) => { var hub_report = new StringBuilder(); hub_report.Append("<h1>" + id + "</h1>\n"); var hub_report_uri = BlobStorage.MakeAzureBlobUri(id, id + ".stats.html"); var hub_report_html = HttpUtils.FetchUrl(hub_report_uri).DataAsString(); var doc = new HtmlDocument(); doc.LoadHtml(hub_report_html); hub_report.AppendLine("<table style=\"border-spacing:6px\" class=\"icalstats\">"); var table = doc.DocumentNode.SelectSingleNode("//table"); hub_report.AppendLine(table.WriteContentTo()); hub_report.AppendLine("</table>"); lock (chunks) { chunks[id] = hub_report.ToString(); // to enable sorted output } } ); foreach (var id in ids) region_report.AppendLine(chunks[id]); var region_calinfo = Utils.AcquireCalinfo(region); var report = Utils.EmbedHtmlSnippetInDefaultPageWrapper(region_calinfo, region_report.ToString()); bs.PutBlob(region, region + ".stats.html", report, "text/html"); }
public static void ProcessIcal(string id) { var calinfo = Utils.AcquireCalinfo(id); GenUtils.LogMsg("status", "worker starting on ical tasks for " + id, null); var fr = new FeedRegistry(id); DoIcal(fr, calinfo); }
public static void EnsureTaskRecord(string id, TaskType type) { if (Scheduler.ExistsTaskRecordForId(id, type) == false) { GenUtils.LogMsg("status", "MaybeCreateTaskRecord: creating task for " + id, null); Scheduler.InitTaskForId(id, type); } }
public static void StoreTaskForId(Task task, string id, TaskType type) { task.hostname = System.Net.Dns.GetHostName(); var dict_obj = ObjectUtils.ObjToDictObj(task); var tasktable = type.ToString(); var ts_response = TableStorage.UpmergeDictToTableStore(dict_obj, table: tasktable, partkey: master_pk, rowkey: id); GenUtils.LogMsg("status", "Scheduler.StoreTaskForId: " + id, null); }
public override void OnStop() { var msg = "Worker: OnStop"; GenUtils.LogMsg("status", msg, null); GenUtils.PriorityLogMsg("status", msg, null); var snapshot = Counters.MakeSnapshot(Counters.GetCounters()); monitor.StoreSnapshot(snapshot); base.OnStop(); }
public static void ProcessRegion(string region) { if ( ! Utils.IsRegion (region) ) throw new Exception(String.Format("ProcessRegion called erroneously for {0}", region)); GenUtils.LogMsg("status", "worker starting on region tasks for " + region, null); var calinfo = Utils.AcquireCalinfo(region); try { var es_region = new ZonelessEventStore(calinfo); var ids = Utils.GetIdsForRegion(region); Parallel.ForEach(source: ids, body: (id) => { var uri = BlobStorage.MakeAzureBlobUri(id, id + ".zoneless.obj", false); var es = (ZonelessEventStore)BlobStorage.DeserializeObjectFromUri(uri); foreach (var evt in es.events) { evt.categories += "," + id.ToLower(); // so tag viewer can slice region by hub name lock (es_region) { es_region.events.Add(evt); } } } ); Utils.UpdateFeedCountForId(region); ZonelessEventStore.Finalize(calinfo, es_region); CacheUtils.MarkBaseCacheEntryForRemoval(Utils.MakeBaseZonelessUrl(region), Convert.ToInt32(settings["webrole_instance_count"])); RenderTags(region); Utils.TagsByHub(region, authorized: true); Utils.TagsByHub(region, authorized: false); SaveRegionStats(region); ImageSelection.BuildCategoryImagesForHub(region); Utils.SaveQuickStatsForRegion(region); } catch (Exception e) { var msg = "process region: " + region; var data = e.Message + e.StackTrace; GenUtils.PriorityLogMsg("exception", msg, data); } GenUtils.LogMsg("status", "worker done processing region " + region, null); }
public void ViewFilterReturnsOneEvent() { var filterable = this.CreateFilterable(calinfo); GenUtils.LogMsg("status", "ViewFilterReturnsOneEvent before", ShowEventStore(filterable.events)); var events = cr.Filter("music", 0, DateTime.MinValue, DateTime.MinValue, null, filterable, new Dictionary <string, object>()); GenUtils.LogMsg("status", "ViewFilterReturnsOneEvent after", ShowEventStore(events)); Assert.That(events.Count == 1); Assert.That(events.First().title == "e5"); }
public static void FinalizeHub(string id) { if (Utils.IsRegion(id)) throw new Exception(String.Format("FinalizeHub called erroneously for {0}", id)); GenUtils.LogMsg("status", "worker finalizing hub: " + id, null); Utils.UpdateFeedCountForId(id); var calinfo = Utils.AcquireCalinfo(id); EventStore.CombineZonedEventStoresToZonelessEventStore(id, settings); // Create or update an entry in the cacheurls table for the base object. // key is http://elmcity.blob.core.windows.net/ID/ID.zoneless.obj // value is # of webrole instances that could be holding this in cache // each instance will check this table periodically. if value is nonzero and url in cache, it'll evict the object // and decrement the count // note when removal occurs it also triggers a purge of dependencies, so if the base entry is // http://elmcity.blob.core.windows.net/a2cal/a2cal.zoneless.obj // then dependencies also ousted from cache include: // /services/a2cal/html?view=&count=0 // /services/a2cal/rss?view=government // /services/a2cal/xml?view=music&count=10 ... etc. CacheUtils.MarkBaseCacheEntryForRemoval(Utils.MakeBaseZonelessUrl(id), Convert.ToInt32(settings["webrole_instance_count"])); RenderTags(id); // static renderings, mainly for debugging now that GetEvents uses dynamic rendering var fr = new FeedRegistry(id); fr.LoadFeedsFromAzure(FeedLoadOption.all); if (calinfo.hub_enum == HubType.where) { SaveWhereStats(fr, calinfo); Utils.SaveMeetupLocations(calinfo, settings); } if (calinfo.hub_enum == CalendarAggregator.HubType.what) SaveWhatStats(fr, calinfo); //if (!Utils.IsRegion(id)) // MergeIcs(calinfo); // else // todo: create MergeRegionIcs Utils.VisualizeTagSources(id); ImageSelection.BuildCategoryImagesForHub(id); GenUtils.LogMsg("status", "worker done finalizing hub " + id, null); }
public static void InitTaskForId(string id, TaskType type) { Scheduler.UnlockId(id, type); var task = new Task(id); var dict_obj = ObjectUtils.ObjToDictObj(task); var tasktable = type.ToString(); var ts_response = TableStorage.UpdateDictToTableStore(dict_obj, table: tasktable, partkey: master_pk, rowkey: id); var http_response = ts_response.http_response; GenUtils.LogMsg("status", "Scheduler.InitTaskForId: " + id, http_response.status.ToString()); }
public static void StopTaskForId(string id, TaskType type) { var task = new Dictionary <string, object>(); task["id"] = id; task["stop"] = DateTime.UtcNow; task["status"] = TaskStatus.stopped.ToString(); var tasktable = type.ToString(); var ts_response = TableStorage.UpmergeDictToTableStore(task, table: tasktable, partkey: master_pk, rowkey: id); GenUtils.LogMsg("status", "Scheduler.StopTaskForId: " + id, ts_response.http_response.status.ToString()); }
/* # runs blobroot/monitor.py # pull 48 hours of diagnostics from odata feed into a file # run logparser queries against the file # output charts (gifs) and/or tables (htmls) to charts container in azure storage # calls blobroot/dashboard.py to update pages that include charts and tables */ public static void MonitorAdmin(object o, ElapsedEventArgs args) { GenUtils.LogMsg("status", "MonitorAdmin", null); try { PythonUtils.RunIronPython(local_storage_path, CalendarAggregator.Configurator.monitor_script_url, new List<string>() { "", "", "" }); } catch (Exception e) { GenUtils.LogMsg("exception", "MonitorAdmin", e.Message + e.StackTrace); } }
private static bool AcquireLock(string id, TaskType type) { var lock_response = Scheduler.LockId(id, type); if (lock_response.status != HttpStatusCode.Created) { GenUtils.LogMsg("warning", "LockId", "expected to create lock but could not"); return false; } else return true; }
public static void MaybeRemakeWebRoleData() { var webrole_sentinel_uri = BlobStorage.MakeAzureBlobUri("admin", CalendarAggregator.Configurator.webrole_sentinel, false); if (BlobStorage.ExistsBlob(webrole_sentinel_uri)) { var list = HttpUtils.FetchUrl(webrole_sentinel_uri).DataAsString(); GenUtils.LogMsg("status", "worker role remaking wrd for " + list, null); var args = new Dictionary<string, string>(); WebRoleData.MakeWebRoleData(); bs.DeleteBlob("admin", CalendarAggregator.Configurator.webrole_sentinel); } }
private static void HandleFeedAdds(string id, List <Dictionary <string, string> > list_metadict_str, List <string> current_feed_urls, List <string> existing_feed_urls) { var added_feed_urls = current_feed_urls.Except(existing_feed_urls); foreach (string added_feed_url in added_feed_urls) { var rowkey = TableStorage.MakeSafeRowkeyFromUrl(added_feed_url); var entity = (Dictionary <string, string>)list_metadict_str.Find(feed => feed["feedurl"] == added_feed_url); TableStorage.UpdateDictToTableStore(ObjectUtils.DictStrToDictObj(entity), "metadata", id, rowkey); } GenUtils.LogMsg("status", "UpdateFeedsForId: find deleted and delete", null); }
private static List <string> HandleFeedDeletes(string id, TableStorage ts, List <string> current_feed_urls, List <string> existing_feed_urls) { var deleted_feed_urls = existing_feed_urls.Except(current_feed_urls); foreach (string deleted_feed_url in deleted_feed_urls) { var rowkey = TableStorage.MakeSafeRowkeyFromUrl(deleted_feed_url); ts.DeleteEntity("metadata", id, rowkey); } GenUtils.LogMsg("status", "UpdateFeedsForId: find updated and update", null); return(deleted_feed_urls.ToList()); }
// runs _admin.py from blobroot/admin, most duties have migrated out of python and into c# public static void IronPythonAdmin(object o, ElapsedEventArgs e) { try { GenUtils.LogMsg("status", "IronPythonAdmin", null); PythonUtils.RunIronPython(local_storage_path, CalendarAggregator.Configurator.iron_python_admin_script_url, new List<string>() { "", "", "" }); } catch (Exception ex) { GenUtils.LogMsg("exception", "IronPythonAdmin", ex.Message + ex.StackTrace); } }
public override bool OnStart() { var local_resource = RoleEnvironment.GetLocalResource("LocalStorage1"); GenUtils.LogMsg("status", "LocalStorage1", local_resource.RootPath); RoleEnvironment.Changing += RoleEnvironmentChanging; var msg = String.Format("WebRole OnStart: {0} {1} {2} {3}", procname, procid, domain_name, thread_id); GenUtils.PriorityLogMsg("info", msg, null); return(base.OnStart()); }
public static HttpResponse UpdateStartTaskForId(string id, TaskType type) { var task = new Dictionary <string, object>(); task["id"] = id; task["start"] = DateTime.UtcNow; task["status"] = TaskStatus.running.ToString(); task["hostname"] = System.Net.Dns.GetHostName(); var tasktable = type.ToString(); var ts_response = TableStorage.UpmergeDictToTableStore(task, tasktable, partkey: master_pk, rowkey: id); var http_response = ts_response.http_response; GenUtils.LogMsg("status", "Scheduler.UpdateStartTaskForId: " + id, http_response.status.ToString()); return(http_response); }
public static void MakeTablesAndCharts(Object o, ElapsedEventArgs e) { GenUtils.LogMsg("status", "MakeTablesAndCharts", null); try { PythonUtils.RunIronPython(WebRole.local_storage_path, CalendarAggregator.Configurator.charts_and_tables_script_url, new List <string>() { "", "", "" }); } catch (Exception ex) { GenUtils.PriorityLogMsg("exception", "MakeTablesAndCharts", ex.Message + ex.StackTrace); } }
public static void RenderTags(string id) { var cr = Utils.AcquireRenderer(id); try { var es = ObjectUtils.GetTypedObj<ZonelessEventStore>(id, id + ".zoneless.obj"); var tags = cr.MakeTagCloud(es); var tags_json = JsonConvert.SerializeObject(tags); bs.PutBlob(id, CalendarAggregator.Configurator.tags_json, tags_json); } catch (Exception e) { GenUtils.LogMsg("exception", "save tags_json: " + id, e.Message + e.StackTrace); } }
public static void TestRunnerAdmin(object o, ElapsedEventArgs args) { GenUtils.LogMsg("status", "TestRunnerAdmin", null); var calinfo = new Calinfo(ElmcityUtils.Configurator.azure_compute_account); try { var ca_failed = GenUtils.RunTests("CalendarAggregator"); var eu_failed = GenUtils.RunTests("ElmcityUtils"); //failed += GenUtils.RunTests("WorkerRole"); //failed += GenUtils.RunTests("WebRole"); var clean = (ca_failed == "" && eu_failed == ""); var msg = clean ? "clean at " : "failures at "; bs.PutBlob("admin", "testrunner", msg + "\n" + ca_failed + "\n" + eu_failed + "\n" + System.DateTime.UtcNow.ToString(), "text/plain"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "TestRunnerAdmin", e.Message + e.StackTrace); } }
public static void SaveWhereStats(FeedRegistry fr, Calinfo calinfo) { var id = calinfo.id; GenUtils.LogMsg("status", "SaveWhereStats: " + id, null); NonIcalStats estats = GetNonIcalStats(NonIcalType.eventful, id, calinfo, settings); NonIcalStats ustats = GetNonIcalStats(NonIcalType.upcoming, id, calinfo, settings); NonIcalStats ebstats = GetNonIcalStats(NonIcalType.eventbrite, id, calinfo, settings); NonIcalStats fbstats = GetNonIcalStats(NonIcalType.facebook, id, calinfo, settings); Dictionary<string, IcalStats> istats = GetIcalStats(id); var where = calinfo.where; string[] response = Utils.FindCityOrTownAndStateAbbrev(where); var city_or_town = response[0]; var state_abbrev = response[1]; int pop = Utils.FindPop(id, city_or_town, state_abbrev); var futurecount = 0; futurecount += estats.eventcount; futurecount += ustats.eventcount; futurecount += ebstats.eventcount; var sb_report = new StringBuilder(); sb_report.Append(MakeTableHeader()); var options = new ParallelOptions(); Parallel.ForEach(source: fr.feeds.Keys, parallelOptions: options, body: (feedurl) => // foreach (var feedurl in fr.feeds.Keys) { StatsRow(id, istats, sb_report, ref futurecount, feedurl); } ); sb_report.Append("</table>\n"); var events_per_person = Convert.ToInt32(futurecount) / (float)pop; var report = Utils.EmbedHtmlSnippetInDefaultPageWrapper(calinfo, sb_report.ToString()); bs.PutBlob(id, id + ".stats.html", new Hashtable(), Encoding.UTF8.GetBytes(report), "text/html"); var dict = new Dictionary<string, object>(); dict.Add("events", futurecount.ToString()); dict.Add("events_per_person", string.Format("{0:f}", events_per_person)); TableStorage.UpmergeDictToTableStore(dict, "metadata", id, id); }
public static void MergeIcs(Calinfo calinfo) { var id = calinfo.id; GenUtils.LogMsg("status", "MergeIcs: " + id, null); List<string> suffixes = new List<string>() { "ical" }; if (calinfo.hub_enum == HubType.where) foreach (NonIcalType type in Enum.GetValues(typeof(CalendarAggregator.NonIcalType))) { if (Utils.UseNonIcalService(type, settings, calinfo) == true) suffixes.Add(type.ToString()); } try { var all_ical = new iCalendar(); Collector.AddTimezoneToDDayICal(all_ical, calinfo.tzinfo); foreach (var suffix in suffixes) // todo: skip if disabled in settings { var url = MakeIcsUrl(id, suffix); try { var feedtext = HttpUtils.FetchUrl(url).DataAsString(); var sr = new StringReader(feedtext); var ical = iCalendar.LoadFromStream(sr).First().Calendar; all_ical.MergeWith(ical); } catch (Exception e) { GenUtils.LogMsg("warning", "MergeICS: " + url, e.Message); } } var serializer = new DDay.iCal.Serialization.iCalendar.iCalendarSerializer(all_ical); var icsbytes = Encoding.UTF8.GetBytes(serializer.SerializeToString(all_ical)); bs.PutBlob(id, id + ".ics", new Hashtable(), icsbytes, "text/calendar"); } catch (Exception e) { GenUtils.LogMsg("exception", "MergeIcs: " + id, e.Message + e.StackTrace); } }
public override bool OnStart() { try { var hostname = System.Net.Dns.GetHostName(); var msg = "Worker: OnStart: " + hostname; GenUtils.PriorityLogMsg("status", msg, null); HttpUtils.Wait(startup_delay); local_storage_path = RoleEnvironment.GetLocalResource("LocalStorage1").RootPath; RoleEnvironment.Changing += RoleEnvironmentChanging; GenUtils.LogMsg("status", "LocalStorage1", local_storage_path); // PythonUtils.InstallPythonStandardLibrary(local_storage_path, ts); HttpUtils.SetAllowUnsafeHeaderParsing(); //http://www.cookcomputing.com/blog/archives/000556.html Utils.ScheduleTimer(IronPythonAdmin, minutes: CalendarAggregator.Configurator.ironpython_admin_interval_hours * 60, name: "IronPythonAdmin", startnow: false); Utils.ScheduleTimer(GeneralAdmin, minutes: CalendarAggregator.Configurator.worker_general_admin_interval_hours * 60, name: "GeneralAdmin", startnow: false); Utils.ScheduleTimer(TestRunnerAdmin, minutes: CalendarAggregator.Configurator.testrunner_interval_hours * 60, name: "TestRunnerAdmin", startnow: false); Utils.ScheduleTimer(ReloadMonitorCounters, minutes: CalendarAggregator.Configurator.worker_reload_interval_hours * 60, name: "WorkerReloadCounters", startnow: false); Utils.ScheduleTimer(MonitorAdmin, minutes: CalendarAggregator.Configurator.worker_gather_monitor_data_interval_minutes, name: "GatherMonitorData", startnow: false); monitor = ElmcityUtils.Monitor.TryStartMonitor(CalendarAggregator.Configurator.process_monitor_interval_minutes, CalendarAggregator.Configurator.process_monitor_table); } catch (Exception e) { var msg = "Worker.OnStart"; GenUtils.PriorityLogMsg("exception", msg, e.Message + e.StackTrace); } return base.OnStart(); }
public HttpResponse SaveStatsToAzure() { var entity = new Dictionary <string, object>(); entity["PartitionKey"] = entity["RowKey"] = this.id; var events_loaded = 0; foreach (var feedurl in this.feeds.Keys) { if (this.stats.ContainsKey(feedurl)) { var ical_stats = this.stats[feedurl]; events_loaded += ical_stats.loaded; } else { GenUtils.LogMsg("warning", "FeedRegistry.SaveStatsToAzure", "stats dict does not contain expected feedurl " + feedurl); } } entity["ical_events"] = events_loaded; return(this.ts.MergeEntity("metadata", this.id, this.id, entity).http_response); }
private void MakeWhereAndWhatAndRegionIdLists() { this.where_ids = Metadata.LoadHubIdsFromAzureTableByType(HubType.where); var where_ids_as_str = string.Join(",", this.where_ids.ToArray()); GenUtils.LogMsg("info", "where_ids: " + where_ids_as_str, null); this.what_ids = Metadata.LoadHubIdsFromAzureTableByType(HubType.what); var what_ids_as_str = string.Join(",", this.what_ids.ToArray()); GenUtils.LogMsg("info", "what_ids: " + what_ids_as_str, null); this.region_ids = Metadata.LoadHubIdsFromAzureTableByType(HubType.region); var region_ids_as_str = string.Join(",", this.region_ids.ToArray()); GenUtils.LogMsg("info", "region_ids: " + region_ids_as_str, null); Dictionary <string, string> ids_and_locations = Metadata.QueryIdsAndLocations(); this.where_ids.Sort((a, b) => ids_and_locations[a].ToLower().CompareTo(ids_and_locations[b].ToLower())); this.what_ids.Sort(); }