public async Task HandleRequest(IOwinContext context) { var pocket = context.Request.Query["pocket"]; var board = context.Request.Query["board"]; var callback = context.Request.Query["callback"]; if (string.IsNullOrWhiteSpace(board)) { board = string.Empty; } var odds = new TexasHoldemOdds { Pocket = HoldemOddsCalculator.SortCards(pocket), Board = HoldemOddsCalculator.SortCards(board) }; var cacheOdds = Cache.Get(odds.GetCacheKey()) as TexasHoldemOdds; if (cacheOdds == null) { Cache.Add(odds.GetCacheKey(), odds, _policy); var calculator = new HoldemOddsCalculator(); cacheOdds = await calculator.Calculate(odds, o => Cache.Set(odds.GetCacheKey(), odds, _policy)); } //check If-None-Match header etag to see if it matches our data hash else if (context.Request.Headers["If-None-Match"] == cacheOdds.GetETag()) { //if it does return 304 Not Modified context.Response.StatusCode = 304; return; } var jsonData = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(cacheOdds)); var result = string.Empty; if (string.IsNullOrWhiteSpace(callback)) { context.Response.ContentType = "application/json"; result = jsonData; } else { context.Response.ContentType = "application/javascript"; result = callback + "(" + jsonData + ");"; } //set the response as cached for cache duration context.Response.Headers["Cache-Control"] = string.Format("max-age={0}", CACHE_DURATION_SECS); //set etag context.Response.ETag = cacheOdds.GetETag(); //Just in case, handle CORS context.Response.Headers["Access-Control-Allow-Origin"] = "*"; await context.Response.WriteAsync(result); }
static void Main(string[] args) { Console.WriteLine(Assembly.GetExecutingAssembly().GetName().FullName); Console.WriteLine(); if (args.Length < 1) { Console.WriteLine("Please specifiy output folder path"); return; } _outputPath = args[0]; Directory.CreateDirectory(_outputPath); bool overwrite = false; if (args.Length > 1) { if (args[1].Equals("/overwrite", StringComparison.InvariantCultureIgnoreCase)) { overwrite = true; } } var deck = GenerateDeck(); var calculator = new HoldemOddsCalculator(); var tasks = new List <Task>(); for (int i = 0; i < deck.Count; i++) { for (int j = 0; j < deck.Count; j++) { //must be different cards if (i != j) { var odds = new TexasHoldemOdds { Pocket = HoldemOddsCalculator.SortCards(string.Format("{0} {1}", deck[i], deck[j])), Board = String.Empty }; //if the file exists, and we are not overwriting, skip these cards if (!overwrite && File.Exists(Path.Combine(_outputPath, string.Format("{0}.json", odds.GetCacheKey())))) { Console.WriteLine("Skipping odds for pocket {0}", odds.Pocket); continue; } Console.WriteLine("Generating odds for pocket {0}", odds.Pocket); var calculateTask = calculator.Calculate(odds, o => Console.WriteLine("Updated odds for pocket {0}", o.Pocket)); calculateTask.ContinueWith(t => SaveOdds(t.Result)); tasks.Add(calculateTask); //if we've got enough tasks to keep the processors busy if (tasks.Count >= Environment.ProcessorCount) { //wait for any of them to finish Task.WaitAny(tasks.ToArray(), Timeout.Infinite); //remove any completed tasks int k = 0; while (k < tasks.Count) { if (tasks[k].IsCompleted) { tasks.RemoveAt(k); } else { k++; } } } } } } if (tasks.Count > 0) { //wait for the remainder to complete Task.WaitAll(tasks.ToArray(), Timeout.Infinite); } var outPath = Path.Combine(_outputPath, "PrimeCache.json"); if (File.Exists(outPath)) { File.Delete(outPath); } using (var outputArchive = new StreamWriter(outPath)) { bool firstItem = true; Directory.GetFiles(_outputPath, "*.json") .Where(filePath => !filePath.Equals(outPath, StringComparison.InvariantCultureIgnoreCase)) .ToList().ForEach(filePath => { if (firstItem) { outputArchive.Write("["); firstItem = false; } else { outputArchive.WriteLine(","); } using (var inputStream = new StreamReader(filePath)) { outputArchive.Write(inputStream.ReadToEnd()); } }); outputArchive.WriteLine("]"); } Console.WriteLine("Job Done"); }