F# and SignalR Stock Ticker: Part 2

Following up on my prior post found here about using F# to write the Stock Ticker example found on SignalR’s website, I went to implement the heart of the application – the stock ticker class.

The original C# class suffers from a violation of command/query separation and also does a couple of things.  Breaking out the code functionality, the class creates a list of random stocks in the constructor. 

image

Then there is a timer that loops and periodically updates the current stock price. 

image

Finally, it broadcasts the new stock price to any connected clients.

image

Because the class depends on the clients for its creation and lifetime, it implements the singleton pattern – you access the class via its Instance property.  This is a very common pattern:

  1. //Singleton instance
  2. private readonly static Lazy<StockTicker> _instance =
  3.     new Lazy<StockTicker>(() =>
  4.         new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));

  1. public static StockTicker Instance
  2. {
  3.     get
  4.     {
  5.         return _instance.Value;
  6.     }
  7. }

Attacking the class from a F# point of view, I first addressed the singleton pattern.  I checked out the Singleton pattern in Liu’s F# for C# Developers. The sentience that caught my eye was “An F# value is immutable by default, and this guarantees there is only on instance.” (p149)  Liu then goes and builds an example using a private class and shows how to reference it via a Instance method.  My take-away from the example is that you don’t need a Singleton pattern in F# – because everything is Singleton by default.  Another way to look at it is that a Singleton pattern is a well-accepted workaround the limitations that mutability brings when using C#.

I then jumped over to the updating stock prices – after all, how can you send out a list of new stock prices if you can’t mutate the list or the individual stocks within the list?  Quite easily, in fact.

The first thing I did was to create a StockTicker class that takes in a SignalR HubContext and a list of stocks.

  1. type StockTicker(clients: IHubConnectionContext, stocks: IEnumerable<Stock>) = class

I then added the logic to update the list and stocks.

  1. let rangePercent = 0.002
  2. let updateInterval = TimeSpan.FromMilliseconds(250.)
  3. let updateStockPrice stock:Stock =
  4.     let updateOrNotRandom = new Random()
  5.     let r = updateOrNotRandom.NextDouble();
  6.     match r with
  7.         | r when r <= 1. -> stock
  8.         | _ ->
  9.  
  10.             let random = new Random(int(Math.Floor(stock.Price)))
  11.             let percentChange = random.NextDouble() * rangePercent
  12.             let pos = random.NextDouble() > 0.51
  13.             let change = Math.Round(stock.Price * decimal(percentChange),2)
  14.             let newPrice = stock.Price + change
  15.             new Stock(stock.Symbol, stock.DayOpen, newPrice)
  16. let updatedStocks = stocks
  17.                         |> Seq.map(fun stock -> updateStockPrice(stock))

Looking at the code, the word “update” in the prior sentence is wrong.  I am not updating anything.  I am replacing the list and the stocks with the new price (if determined).  Who needs a singleton?  F# doesn’t.

I then attempted to notify the clients like so:

  1. member x.Clients = clients
  2. member x.Stocks = stocks
  3. member x.BroadcastStockPrice (stock: Stock) =
  4.     x.Clients.All.updateStockPrice(stock)

 

But I got a red squiggly line of approbation (RSLA) on the updateStockPrice method.  The compiler is complaining that

Error    1    The field, constructor or member ‘updateStockPrice’ is not defined   

And reading the SignalR explanation here:

The updateStockPrice method that you are calling in BroadcastStockPrice doesn’t exist yet; you’ll add it later when you write code that runs on the client. You can refer to updateStockPrice here because Clients.All is dynamic, which means the expression will be evaluated at runtime

So how does F# accommodate the dynamic nature of Clients.All?  I don’t know so off to StackOverflow I go….

In any event, I can then wire up a method that broadcasts the new stock prices like so:

  1. member x.BroadcastAllPrices =
  2.     x.Clients.All.updateAllStockPrices(updatedStocks)

And then write a method that calls this broadcast method every quarter second:

  1.  member x.Start =
  2.      async {
  3.             while true do
  4.              do! Async.Sleep updateInterval
  5.              x.BroadcastAllPrices
  6.      } |> Async.StartImmediate

Note that I tried to figure out the Timer class and subsequent Event for the timer, but I couldn’t.  I stumbled upon this post to ditch the timer in favor of the code above and since it works, I am all for it.  Figuring out events in F# is a battle for another day…

 

 

 

F# and SignalR Stock Ticker Example

I was looking at the server broadcast SignalR tutorial found here for a current project when I got to the StockTicker class.  In this class, the interesting code surrounds making a singleton instance because SignalR hubs are transient.  Here is the full text:

You’ll use the SignalR Hub API to handle server-to-client interaction. A StockTickerHub class that derives from the SignalR Hub class will handle receiving connections and method calls from clients. You also need to maintain stock data and run a Timer object to periodically trigger price updates, independently of client connections. You can’t put these functions in a Hub class, because Hub instances are transient. A Hub class instance is created for each operation on the hub, such as connections and calls from the client to the server. So the mechanism that keeps stock data, updates prices, and broadcasts the price updates has to run in a separate class, which you’ll name StockTicker.

So then it hit me – we need an immutable class that can handle multiple requests.  This sounds like a job for Captain F#!  Unfortunately, Captain F# is on vacation, so I went with Private 1st class F#.  So this is what I did.

I created an empty solution.  I then added in a C# Empty Web Application just to have a point of comparison to the FSharp project.  Then I added in a new F# MVC4 project from on the on-line template that Daniel Mohl created:

image

The problem is that the C# is the web app and the F# is just the controller.  Since I want a full-on double rainbow F# only MVC application, I tossed the template and just created a bare-bones F# project.  I then opened the .fsproj file and added a web ProjectType GUID (basically parroting what was in the .cs project file):

image

I posted this to stack overflow here.  So I am back to using C# as the Web application and F# as the plug in code.  I re-started with a couple of skeleton projects like so:

image

I then added a class for Stock like so:

  1. namespace Tff.SignalRServerBroadcast.FS
  2.  
  3. open System
  4.  
  5. type Stock() =
  6.     member val Symbol = String.Empty with get, set

 

I then added some unit tests to verify that I could create the Stock class and that I could assign the Symbol property:

  1. [TestClass]
  2. public class StockTests
  3. {
  4.     [TestMethod]
  5.     public void CreateStock_ReturnsValidInstance()
  6.     {
  7.         Stock stock = new Stock();
  8.         Assert.IsNotNull(stock);
  9.     }
  10.  
  11.     [TestMethod]
  12.     public void VerifyStockSymbolCanBeMutated()
  13.     {
  14.         Stock stock = new Stock();
  15.         stock.Symbol = "TEST";
  16.  
  17.         String notExpected = String.Empty;
  18.         String actual = stock.Symbol;
  19.  
  20.         Assert.AreNotEqual(notExpected, actual);
  21.     }
  22. }

 

And sure enough, they run green:

image

Just then, Captain F# swooped in from vacation and exclaimed “What are you doing?  The tenants of functional programming is immutability.  What happens if you change the Symbol after the object is created – does it really represent the same thing?  In fact, allowing the Symbol to be changed after it is created will lead to bugs and potentially unexpected behaviors in your system!”  With that, he left for a 10-day tour of the eastern Mediterranean.

I then changed the Stock class to be immutable like so:

  1. namespace Tff.SignalRServerBroadcast.FS
  2.  
  3. open System
  4.  
  5. type Stock =
  6.     {Symbol: String;
  7.      Price: Decimal;
  8.      DayOpen: Decimal;
  9.      }
  10.  
  11.      member x.GetChange () =
  12.         x.Price – x.DayOpen

 

and then updated my unit tests like so:

  1. [TestClass]
  2. public class StockTests
  3. {
  4.     [TestMethod]
  5.     public void CreateStock_ReturnsValidInstance()
  6.     {
  7.         Stock stock = new Stock("TEST", 10, 10.25M);
  8.         Assert.IsNotNull(stock);
  9.     }
  10.  
  11.     [TestMethod]
  12.     public void PriceChangeUsingValidNumbers_ReturnsCorrectChange()
  13.     {
  14.         Stock stock = new Stock("TEST", 10, 10.25M);
  15.         Decimal expected = .25M;
  16.         Decimal actual = stock.GetChange();
  17.         Assert.AreEqual(expected, actual);
  18.     }
  19. }

And then I ran my tests and got red

image

Ugh, I reversed the parameters – I intended to have the stock go up $.25.  Instead, the constructor expects the Price to come before the DayOpen.  This is not intuitive – you have implicit temporal coupleing in these parameters and since DayOpen occurs sooner in the space-time continuum, I reversed the parameters and the tests ran green:

  1. type Stock =
  2.     {Symbol: String;
  3.      DayOpen: Decimal;
  4.      Price: Decimal;
  5.      }

 

image

With that done, I looked at the last PercentChange  calculation.  The only thing remarkable about it is that the code in the on-line tutorial is incorrect.  The tutorial uses Price as the denominator, but my unit tests shows that it wrong:

  1. [TestMethod]
  2. public void PercentChangeUsingValidNumbers_ReturnsCorrectChange()
  3. {
  4.     Stock stock = new Stock("TEST", 10, 11M);
  5.     Decimal expected = .1M;
  6.     Decimal actual = stock.GetPercentChange();
  7.     Assert.AreEqual(expected, actual);
  8. }

 

image

If a stock goes from $10.00 to $11.00, it increases $1.00 and $1.00 divided by $10.00 is 10% – the stock increased 10%.

So I went back and changed the implementation to get the test to run green.

  1. member x.GetPercentChange() =
  2.     Math.Round(x.GetChange()/x.DayOpen,4)

 

image

 

So looking at this class, why is F# better than C#?

1) Less noise.  Compare the code between C# and F#

imageimage

All of the code in the Price setter is irrelevant.  In the F# implementation, you don’t need to worry about assigning DayOpen for the 1st time. 

 

2) Fewer Bugs: 

What happens if you are looking at Pets.com (IPET) on November 6, 2000 when it opened at $.16 and then went to $0.00 at noon when they finalized their liquidation?  You need to change your code b/c the C# implementation is wrong – the price was $0.00 and it was not the open price.

Also, what prevents me from changing the Symbol?  I could create a ticker class for APPL at $519 and then change the ticker to MSFT – volia MSFT’s price goes from $37.57 to $519.00!  And all of the unit tests for the Stock still run green.

3) More readable. 

Less noise – more signal (SignalR in fact)…

 

This blog post is getting a bit long so I will continue this project on another post.

Thanks to the RHCP, I listened to this 2-3 times when doing this blog post…

SignalR: 1st Project

So I wanted to learn more about SignalR so I went over to GitHib and checked out their getting started page.  The page makes some assumptions that a new .NET developer might run into so I thought I would show how I got it working.

Step #1: Open Visual Studio 2012 and File->NewProject  and select ASP.NET Empty Web Application:

image I

Note that I made the solution name different than the name of the project because I will be added another project to this solution.

Step #2: Add a new console application to the solution:

image

Your solution should now look like this:

image

Step #3: Go to the Server project and open the NuGet Package Manager Console:

image

In the Package Manager Console Window, type

Install-Package Microsoft.AspNet.SignalR

Make sure that the Default Project is the Server project you created

image

after you hit enter, NuGet will do a bunch of stuff for you (adding libraries, resolving dependencies, etc…) and open the readme.txt file.  You can close that window.

Step #4: Add a class to your server project  called MyConnection (you are using Shift+Alt+C aren’t you?):

image

Step #5: Type (or copy) the code into your MyConnection class.  Note that you are inheriting from the PersistentConnection class and you will have to resolve (CTRL+.) both that class and the Task class.

image

Your class should look like this:

image

Step #6: Add a Global.asax file to your server project

image

Then type(or copy) the code into your Application_Start event handler:

image

Note that you will have to resolve the RouteTable class (CTRL+.).

The server project is now ready to go.  Make sure the server project is the startup project and run it.  IE will launch and you will get a web page like this:

image

Make a note of the address.  You can then stop the project from running.

Step #7: Go to the Client project and open the NuGet Package Manager Console and install the SignalR Client package.  Important, make sure that the default project is pointed to the client project

image

Step #8 Go to the Program.Main method and type (or copy) the code in.  Note that you will have to resolve the Connection class

image

Note that the address for the connection will be different for your machine.  Match that connection address back to the uri that IE showed you when you ran the server project.

Step #9: Open up the Configuration of the solution file and change the solution to have multiple startup projects.  Make sure you change the order so the client starts AFTER the server

image

Step #10 Run the solution and make the console window have focus.  Type in something and see the server push that message back out to you

image