Archive for the ‘Software Development’ Category


Index:

IPTV #1: Introduction
IPTV #2: Video Signal Path
IPTV #3: DISH Command Signal Path

One of the cool things about being a software developer is that occasionally you get to work on some really neat projects.

Last year, the taxpayers of Nez Perce County, my employer, authorized the construction of a new jail facility. As part of the construction of this facility we were tasked with implementing an IPTV system for the inmates (I’m not much for giving prisoners access to television, but this is a legal requirement).

There are IPTV solutions on the market, but our research found them to be really expensive. As a county government we’re funded by taxpayers, of which I am one. So in a way, I work for myself, as do many of our employees who hold residence in Nez Perce County. Taxpayers like to keep costs down, so we looked at building our own IPTV solution.

The project was really fun and one of the most interesting projects I’ve worked on as a professional developer. Mainly because of the disparate technologies involved and the process of bringing all of these different pieces together into a cohesive and working solution. Several people in our department contributed to the success of the project; we did a ton of research into hardware solutions and worked hard to find the right mix of hardware and software so that we could achieve our goals and yet still succeed on a relatively small budget. The result of our effort was a combination of hardware and software that allowed us to multicast DISH Network satellite streams over an isolated internal network and to remotely control the television sets with a client-server software package written entirely from scratch in C#.Net.

With the system we created, the control of the televisions (channel changing, volume, power) was taken out of the inmates hands. Thus, the inmates do not have access to small, plastic remote controls that can be easily broken (and cost money to replace) and used as weapons. Instead, our jailers control the televisions remotely through a Windows application:

IPTV Main Client Screen

To build this system we had to utilize a lot of different technologies:

Hardware:

Software

  • C#.Net Client and Server applications
  • NHibernate
  • SQL Server 2005
  • Fluent NHibernate
  • WCF Duplex Channels
  • VideoLAN (Open Source Media Player)

In future posts I’ll detail how we pulled all this together.

On a recent project I worked on I had a need to create a client-server application. What I was after was real-time updating of the clients when data on the server changed. These sorts of applications crop up from time to time in one’s career, and they present a unique set of challenges. I figured I’d store the results of my work on my blog, and if it helps someone else then great.

I am not posting the actual application here because it relies on some machine-specific hardware devices, but what I did instead was to extract the core functionality out into a sample application that shows how the duplex service is constructed and how it is used. I created a simple service that contains a list of Movies. The clients have the ability to add a new Movie to the server, or delete an existing one. There’s no fancy business rules or elaborate domain objects because I’m mostly interested in documenting the duplex service usage.

You can download the application here. It was written in C#, .Net 3.5. It utilizes StructureMap for dependency injection (which I highly recommend) and I’ve included that library with the package. The executable files are included in the corresponding /bin directories so you don’t have to compile the application if you want to see it work.

Notes:

  • The server is a console application. It will write to the console when a client subscribes or unsubscribes from the service, and it will print the count of the remaining subscribers.
  • To see the real-time updating in action, open two clients. Add a new movie title to the list in one client and you’ll see the immediate update in both clients.

WCF Duplex Service Contract

A note about this service: You will notice I am passing .Net objects across the wire with this service. There are no data transfer objects and no requirements for interoperability. I have complete control over both sides of the wire; the client and server applications. And in general, when you are writing a client-server app that’s going to be the case. This is not a “web services” solution; there are plenty of those already.

There is a caveat to creating and using a WCF Duplex service: You have to keep the connection open if you want your client to respond to callbacks. With WCF, once a connection falls into a Faulted state it becomes useless, and there’s no going re-connecting. You have to re-create the connection from scratch.

Normally, when using a one-way service, you only create the connection for as long as it takes you to call the service. But here we want our client to actively listen to callbacks from the service (as opposed to polling the service, which puts the burden for updates on the client and can leave the client with stale data). To make that happen we have to utilize a keepalive call with a timer, so that we ping the service frequently enough to maintain the connection. WCF will timeout a connection after 10 minutes of inactivity due to the way the underlying timeout scheme is written, and I have yet to find a single configuration knob that will allow a connection to live longer than that in a reliable fashion. The keepalive, however, works and is rock solid.

My service implements two interfaces. One is for the plumbing associated with subscribing and unsubscribing to the service, and using a keepalive to maintain the connection to the service. The second interface is the one the client is really interested in, and has all the calls to deal with the data. You don’t have to separate these interfaces; I did because it shields the client from having to see those plumbing methods (they can still get to them if they cast want to it).

The plumbing interface looks like this:

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof (IMovieServiceCallback))]
public interface IDuplexService
{
    [OperationContract]
    bool KeepAlive();

    [OperationContract]
    void Subscribe();

    [OperationContract]
    void Unsubscribe();
}

The second service interface looks like this:

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IMovieServiceCallback))]
public interface IMovieService : IDuplexService
{
    [OperationContract]
    IList<Movie> FindAll();

    [OperationContract]
    bool Exists(string title);

    [OperationContract]
    void Add(string title);

    [OperationContract]
    void Delete(Movie movie);
}

In both cases I’ve decorated the service interface with the [ServiceContract] attribute and specified the [CallbackContract], which looks like this:

public delegate void MoviesChangedEventHandler();

public interface IMovieServiceCallback
{
    event MoviesChangedEventHandler OnMoviesChanged;

    [OperationContract]
    void MoviesChanged();
}

The only thing that’s left to do on the client side is setup the configuration file where we specify the WCF settings and then implement the interface. I’m not going to post the XML here (you can download the sample app to see it, basic WCF stuff). What I will do is post the relevant code inside the service that deals with subscribers.

Service Implementation

The service maintains a list of subscribers which take the form of the IMovieServiceCallback. The three key methods for dealing with the subscribers are thus:

bool IDuplexService.KeepAlive()
{
    return true;
}

void IDuplexService.Subscribe()
{
    var callback = OperationContext.Current.GetCallbackChannel<IMovieServiceCallback>();
    if (!_subscribers.Contains(callback))
        _subscribers.Add(callback);

    RemoveDeadConnections();
}

void IDuplexService.Unsubscribe()
{
    var callback = OperationContext.Current.GetCallbackChannel<IMovieServiceCallback>();
    if (_subscribers.Contains(callback))
        _subscribers.Remove(callback);

    RemoveDeadConnections();
}

The KeepAlive is the simplest thing; just return a boolean. All we really care about is hitting the service to keep it open, and we do that with the aid of a timer in the client’s proxy (which we’ll get to later on).

Where things get interesting is how we handle the manipulation of data. In a one-way service the client would ask the service to create a new Movie and persist it. Once that operation was complete, the client would then proactively ask the service for an updated list of Movies. The client does all the work in this situation, making the requests. That’s fine for one client, but if other clients want to know when the data changes, they have to poll the service.

With a duplex service we tend to make a request of the service and then forget about it; the service will update us (and every other client) when its ready. So deleting a Movie looks like this:

public void Delete(Movie movie)
{
    _repository.Delete(movie);
    _movieCache = _repository.FindAll();
    UpdateSubscribers();
}

The service delegates to a Repository to handle the delete, updates its internal cache, and then makes a call out to all the subscribers, in essence telling them, “Hey, the data has changed. Update yourself”.

Updating the subscribers then becomes a matter of looping through them and calling the method on the callback interface:

private void UpdateSubscribers()
{
    for (int i = _subscribers.Count - 1; i >= 0; i--)
    {
        if (((ICommunicationObject) _subscribers[i]).State == CommunicationState.Opened)
        {
            _subscribers[i].MoviesChanged();
        }
        else
        {
            ((ICommunicationObject) _subscribers[i]).Abort();
            _subscribers.Remove(_subscribers[i]);
        }
    }
}

We are doing one extra step here: getting rid of delinquent subscribers. You see, there’s no easy, event-driven way to determine when a client has faulted or disconnected in a non-nice way. So the best plan is to periodically prune off bad subscribers. In my service, I do this whenever the data changes, and whenever a client subscribes or unsubscribes. It helps keep the subscriber list clean.

Client Proxy

With the service side of things mostly out of the way it’s time to move on to the client. Here I’ve manually created a client proxy (not using svcutil.exe). The proxy class implements the methods from IMovieService. Beyond the methods on the IMovieService interface, the proxy has a few responsibilities:

  1. Create the DuplexChannel and establish the connection to the service.
  2. Subscribe to the service.
  3. Create a Timer and fire the KeepAlive periodically.
  4. Unsubscribe from the service when shutting down.
  5. Respond to callback events from the server and re-fire them in a chain-of-command style pattern to the client.

Connect handles the first three responsibilities:

public void Connect()
{
            _movieServiceCallback = new MovieServiceCallback();
            _movieServiceChannelFactory = new DuplexChannelFactory<IMovieService>(_movieServiceCallback, _movieServiceEndpointConfigurationName);

            _movieService = _movieServiceChannelFactory.CreateChannel();
            ((IContextChannel) _movieService).OperationTimeout = new TimeSpan(0, 0, 0, 30);
            _movieService.Subscribe();
            _movieServiceCallback.OnMoviesChanged += MoviesChanged;

            _timer = new Timer(60000);
            _timer.Elapsed += TimerElapsed;
            _timer.AutoReset = true;
            _timer.Start();
}

A Disconnect method handles the fourth responsibility. Responding to the service is handled by the MovieChanged event, which simply re-fires it:

 private void MoviesChanged()
{
    if (OnMoviesChanged != null)
        OnMoviesChanged();
}

The other thing that I have the proxy do is make asynchronous calls to the service for methods that I know should be asynchronous. An example is Delete():

private delegate void DeleteDelegate(Movie movie);

public void Delete(Movie movie)
{
    DeleteDelegate deleteDelegate = _movieService.Delete;
    AsyncCallback callback = AsyncCompleteMethod;
    deleteDelegate.BeginInvoke(movie, callback, null);
}

private void AsyncCompleteMethod(IAsyncResult ar)
{
}

When the client makes a call to delete, it’s made asynchronously, and the client can immediately return. The UI doesn’t lock up and life goes on for the client. When the service is done processing the delete it will update the subscribers. That’s when they’ll have to respond in a way that doesn’t lock the UI or crash the program.

Client

In my view’s presenter class I take a dependency on the IMovieService interface. By way of StructureMap, the presenter gets the MovieServiceProxy, and we wire up to it’s OnMoviesChanged event:

private IMovieService _movieService;

public ShellPresenter(IMovieService movieService)
{
    _movieService = movieService;
}

public override void OnViewReady()
{
    base.OnViewReady();
    ((IMovieServiceProxy) _movieService).OnMoviesChanged += MoviesChanged;
    MoviesChanged();
}

The MoviesChanged method just queries the service for the list of Movies (which are conveniently cached in the service, so the service isn’t hitting the database every time a client requests the list).

private void MoviesChanged()
{
    View.Movies = _movieService.FindAll();
}

And this is where the trouble occurs if you don’t handle it correctly. We’ve just had what amounts to a background thread inform us to update our view. If we try and do this directly we’re going to get some unpleasant behavior in our UI. So we let the View handle this properly:

public delegate void UpdateMovieListDelegate(IList<Movie> movies);

public IList<Movie> Movies
{
    set
    {

        if (InvokeRequired)
        {
            var args = new object[1];
            args[0] = value;
            BeginInvoke(new UpdateMovieListDelegate(UpdateDataGridView), args);
         }
         else
         {
             UpdateDataGridView(value);
         }
     }
}

 private void UpdateDataGridView(IList<Movie> movies)
{
    _dataGridView.DataSource = null;
    _dataGridView.DataSource = movies;
}

InvokeRequired is a property on Controls, and it’s a convenient way to determine if the update is coming from another thread. If so, we can launch the operation asynchronously on the proper thread, in this case, the UI thread, since controls in .NET can only be updated by the thread they were created on.

Real-time, client-server type applications aren’t terribly difficult to deal with, they just require a different mindset in regards to when things get updated. And then one just has to utilize the asynchronous tools that the .NET framework has provided to make sure things get done in a way that doesn’t cause your application to hang or crash.

Allow me to lay out a story that should sound familiar:

A couple of coworkers are discussing a bug in the software. In this particular bug’s case, it concerns an icon that appears in a column of a datagrid. Each row in the grid is either supposed to have this little icon in a specified column, or not. It depends on the data. But that’s not really important, just background info.

What’s really important is that the icon was previously coded and tested and worked. It appeared under the correct conditions and was hidden when it should be. Now, all of a sudden, it wasn’t working. We get an e-mail from customers saying, “The icon should show up in this circumstance, but it doesn’t.” Time to investigate.

While my two coworkers are hashing out exactly what could have happened, why, and how to fix it, I start thinking to myself, “There should be unit tests to catch this. This shouldn’t have happened. I’ll just go find the test suite and write a couple new tests to ensure the icon properly displays based on the criteria of the data.

Sounds easy, right?

As I started digging through the specific class code and examining the unit tests, I notice that there are no unit tests for this functionality. That seems suspicious. Then I notice something else: there’s no code. All that exists is a method call to a service that returns a datatable.

As Alice did, I decided to drop through the rabbit hole and see what’s up.

When I get to the bottom I see a gigantic SQL statement – several hundred lines long. It is embedded in the application, deep down in the data access layer, complete with multiple sub-selects and even an SQL case statement! It’s got multiple parameters in the where clause. It’s the kind of thing that makes SQL admins all warm and fuzzy inside, I’m sure. The whole thing is then handed off to our OR/M, which returns a simple datatable. While it is not a stored procedure, it might as well have been – it only has one step remaining on the cliff before it jumps right off into the database.

And the killer is, it’s untestable.

The caveat here is that this particular stored procedure was written as a performance gain, because the nature of the data requested is complex in its selection. But still, I’m of the belief that there might be a better way to query the data than one giant stored procedure.

Because the minute you put business logic in a stored procedure you compromise the quality of your application. You introduce the capability for your team to make mistakes that are no longer easily caught by a regression suite of unit tests. More importantly, I think, is that you increase the probability of repeated bugs. And to me, repeated bugs are a cardinal sin of programming. Nothing makes a development team look dumber than fixing a bug only to have it crop up again, and again, and again. It makes the software look bad, and by proxy it makes the developers look incompetent.

Bob, lamenting the continued bloated nature of Windows OS, writes:

Personally I think they should clean house on the OS side, put the development tools in maintenance mode for a couple of years, and put Scott Guthrie and the rest of those geniuses behind Visual Studio to work on building a new OS from scratch.

This is something I’ve been saying for years. Windows needs to be rewritten from scratch. Start over, and let the guiding principal be: Simple Is Better.

Windows has become so big and bloated that it can’t do the basics anymore. I mean, really – what do you need your OS to do? I know what I want my OS to do: run my apps. That’s it; it’s that simple. Manage my files, memory and processes so I can run my apps. And even Windows can’t get that right.

Have you tried working with Explorer lately? Copying large files? Over a network? When was the last time you tried to kill a process in Windows? Guess what? It’s still easier and more reliable to kill a process in Unix/Linux than it is in Windows. Why is that?

As Riply said, “I say we take off, and nuke the site from orbit. It’s the only way to be sure.”

Simon has a new post describing how they’ve revamped their planning board. I found it to be an interesting read because for once someone else’s board looks similar to ours.

Our board has undergone a few makeovers as well over the past couple of years. In the beginning we tried to do what everyone else was doing. We had a big board with several columns. But our shop was small (at it’s peak, three developers and a PM) and the extra columns seemed wasteful. We didn’t really have a QA team, for instance, because we were the QA team. A “Testing” column seemed like a waste because we practice TDD as much as possible, so testing is part of the process of development. Same goes for acceptance tests, hands-on testing and customer approval. It’s all part of the process of developing software. Personally, I don’t look at the different elements – like architecture, design, testing or customer feedback – as separate phases. I see them as the one thing: developing software. They are all necessary elements to reach the final goal of a completed, working, and trusted software feature.

In the end, we finally settled on was the simplest thing that could possibly work: Backlog, In Development & Done.

Our Backlog is every story card in our possession. We don’t categorize; we just let the customer prioritize. In Development is everything we’re working on during this iteration. Since we – the developers – do it all, then In Development carries a comprehensive meaning. And when all the bases are covered, regardless of what order they were performed (although I hope unit tests were written before the code was) then, and only then, does it move to Done.

What I enjoy most about our board is that it is so simple to read. It’s easy to determine what’s left to do (Backlog), what’s being worked on (In Development) and what’s ready for the next publish at the end of the iteration (Done). And I don’t need to worry about testing or customer approval because those elements of the development process are implied.