Mercurial > silverbladetech
diff MetroWpf/Stocks.Service/StocksService.cs @ 20:6109bc268b90
Latest
author | adminsh@apollo |
---|---|
date | Tue, 20 Mar 2012 13:37:46 +0000 |
parents | |
children | dfc81f8bb838 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MetroWpf/Stocks.Service/StocksService.cs Tue Mar 20 13:37:46 2012 +0000 @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using NLog; +using Stocks.Common; +using Stocks.Common.Core; +using Stocks.Common.Events; +using Stocks.Common.Models; + +namespace Stocks.Service +{ + public class StocksService : IStocksService + { + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + + private IList<Company> _companies; + private readonly IConfigurationService _configurationService; + private List<Price> _currentPrices; + private string _serviceUrl; + private readonly IWebClientShim _webClient; + + public bool IsRunning { get; private set; } + public SummaryStats Stats { get; private set; } + + public StocksService( + IConfigurationService configurationService, + IWebClientShim webClientShim) + { + new AssemblyInit(); + + _webClient = webClientShim; + _configurationService = configurationService; + Stats = new SummaryStats(); + + GetCompanyList(); + } + + private void GetCompanyList() + { + _companies = _configurationService.GetCompanies(); + + var symbolsCsv = _companies.Select( + c => c.Symbol).Aggregate((c, d) => c + "," + d); + + _serviceUrl = _configurationService.GetServiceUrl(symbolsCsv); + } + + public IList<Price> GetFullCurrentPrices() + { + return _companies.Select(company => new Price(company.Symbol, 0, 0)).ToList(); + } + + public event PriceChangedEventHandler PriceChanged; + public delegate void PriceChangedEventHandler(object sender, PriceChangedEventArgs e); + protected virtual void OnPriceChanged(Price price) + { + Stats.PriceChangeEvents++; + + if (PriceChanged != null) + PriceChanged(this, new PriceChangedEventArgs() { Price = price }); + } + + public void Start() + { + PrepareForServiceStarting(); + Task.Factory.StartNew(DownloadPrices); + } + + public void Stop() + { + IsRunning = false; + Log.Debug("StockService stopped"); + } + + private void PrepareForServiceStarting() + { + Log.Debug("StockService starting"); + IsRunning = true; + Stats.Reset(); + _currentPrices = new List<Price>(_companies.Count); + } + + private void DownloadPrices() + { + try + { + while (IsRunning) + { + Stopwatch timeToDownload; + var webResponse = TimedDelegates.Execute( + _webClient.DownloadString, + _serviceUrl, + out timeToDownload); + + PopulatePricesFromWebResponse(webResponse); + UpdateStats(timeToDownload, webResponse); + } + } + catch (Exception e) + { + Log.Error("Exception during DownloadPrices()"); + Log.Error("Stack Trace {0}: /r/nException Message: {1}", e.StackTrace, e.Message); + this.Stop(); + } + } + + private void PopulatePricesFromWebResponse(string webResponse) + { + var webPrices = webResponse.Split( + new[] { "\n", "\r\n" }, + StringSplitOptions.RemoveEmptyEntries); + + foreach (var webPriceData in webPrices) + { + var webPrice = Factory.CreatePrice(webPriceData); + var localPrice = _currentPrices.Find(x => x.Symbol == webPrice.Symbol); + + if (localPrice == null) + { + _currentPrices.Add(new Price(webPrice.Symbol, webPrice.CurrentPrice, webPrice.PreviousPrice)); + continue; + } + + if (!localPrice.Equals(webPrice)) + UpdateLocalPrice(webPrice, localPrice); + } + } + + private void UpdateLocalPrice(Price webPrice, Price localPrice) + { + localPrice.PreviousPrice = localPrice.CurrentPrice; + localPrice.CurrentPrice = webPrice.CurrentPrice; + OnPriceChanged(localPrice); + } + + private void UpdateStats(Stopwatch timeToDownload, string webResponse) + { + Stats.LastWebRequest.Duration = (int)timeToDownload.ElapsedMilliseconds; + Stats.LastWebRequest.PricesDownloaded = _currentPrices.Count; + Stats.LastWebRequest.Response = webResponse; + Stats.LastWebRequest.Request = _serviceUrl; + Stats.LastWebRequest.SymbolCount = _companies.Count; + Stats.NumberOfRequests++; + Log.Trace(Stats); + } + } +} \ No newline at end of file