MVC pattern synchronisation

designmultithreadingmvcsynchronization

I am facing a problem in synchronizing my model and view threads

I have a view which is table. In it, user can select a few rows.
I update the view as soon as the user clicks on any row since I don't want the UI to be slow.
This updating is done by a logic which runs in the controller thread below.

At the same time, the controller will update the model data too, which takes place in a different thread. i.e., controller puts the query in a queue, which is then executed by the model thread – which is a single-threaded interface.

As soon as the query executes, controller will get a signal.

Now, In order to keep the view and model synchronized, I will update the view again based on the return value of the query (the data returned by model) – even though I updated the view already for that user action.

But, I am facing issues because, its taking a lot of time for the model to return the result, by that time user would have performed multiple clicks. So, as a result of updating the view again based on the information from model, the view sometimes goes back to the state in which the previous clicks were made

(Suppose user clicks thrice on different rows. I update the view as soon as the click happens. Also, I update the view when I get data back from the model – which is supposed to be same as the already updated state of the view. Now, when the user clicks third time, I get data for the first click from model. As a result, view goes back to a state which is generated by the first click)

Is there any way to handle such a synchronization issue?

Best Answer

You describe a situation in which the user updates three rows. The first transaction completes after the third click, and all three rows update themselves with the stale data.

You need to think about the granularity of your model items. It sounds like you want each row on the UI to represent a single aggregate (transactional boundary). So when an aggregate is updated in the database, you should only update that aggregate's row on the UI.

In other words, I think the events to which your view is binding are too coarse-grained. When a model item is updated in the database, you should consider returning only that item's new state from the back end. Since the commands from the UI are being handled atomically, the resulting events should be atomic too.

Pseudo-C#:

class ViewController
{
    ...
    void RowUpdatedEventHandler(RowUpdatedEvent e)
    {
        var row = this.rows[e.AggregateId];
        row.Name = e.NewName;
        row.Price = e.NewPrice;
    }
}
Related Topic