diff Stocks/Stocks.Service/StocksService.cs @ 0:e5d46bb6cdb0

Initial commit
author adminSH stevenhollidge@hotmail.com
date Mon, 20 Feb 2012 13:52:35 +0700
parents
children 29ed98d659e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Stocks/Stocks.Service/StocksService.cs	Mon Feb 20 13:52:35 2012 +0700
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+using NLog;
+using Stocks.Common;
+using Stocks.Common.Models;
+using Stocks.Common.Events;
+
+namespace Stocks.Service
+{ 
+  public class StocksService : IStocksService
+  {
+    private static readonly Logger Log = LogManager.GetCurrentClassLogger();
+
+    private IList<Company> _companies;
+    private IConfigurationService _configurationService;
+    private List<Price> _currentPrices;
+    private string _serviceUrl;
+    private WebClient _webClient;
+
+    public bool IsActive { get; private set; }
+    public SummaryStats Stats { get; private set; }
+
+    public StocksService(IConfigurationService configurationService)
+    {
+      new AssemblyInit();
+
+      _webClient = new WebClient();
+      _configurationService = configurationService;
+      _companies = configurationService.GetCompanies();
+
+      string symbolsCsv = _companies.Select(
+        c => c.Symbol).Aggregate((c, d) => c + "," + d);
+      _serviceUrl = _configurationService.GetServiceUrl(symbolsCsv);
+      
+      Stats = new SummaryStats();
+    }
+
+    public delegate void PriceChangedEventHandler(object sender, PriceChangedEventArgs e);
+    public event PriceChangedEventHandler PriceChanged;
+    protected virtual void RaisePriceChanged(Price price)
+    {
+      Stats.PriceChangeEvents++;
+
+      if (PriceChanged != null)
+        PriceChanged(this, new PriceChangedEventArgs() { Price = price });
+    }
+
+    public void Start()
+    {
+      PrepareForServiceStarting();
+      Task.Factory.StartNew(() => DownloadPrices());
+    }
+
+    public void Stop()
+    {
+      IsActive = false;
+      Log.Debug("StockService stopped");
+    }
+
+    private void PrepareForServiceStarting()
+    {
+      Log.Debug("StockService starting");
+      IsActive = true;
+      Stats.Reset();
+      _currentPrices = new List<Price>(_companies.Count);
+    }
+
+    private void DownloadPrices()
+    {
+      try
+      {
+        Stopwatch timeToDownload = new Stopwatch();
+
+        while (IsActive)
+        {
+          timeToDownload.Restart();
+          string webResponse = _webClient.DownloadString(_serviceUrl);
+          timeToDownload.Stop();
+
+          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)
+    {
+      string[] webPrices = webResponse.Split(
+        new string[] { "\n", "\r\n" },
+        StringSplitOptions.RemoveEmptyEntries);
+
+      foreach (string 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)) {
+          continue;
+        }
+        else {
+          localPrice.PreviousPrice = localPrice.CurrentPrice;
+          localPrice.CurrentPrice = webPrice.CurrentPrice;
+          RaisePriceChanged(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