locked
Updating local repository RRS feed

  • Question

  • Hello, I have a desktop application that hosts the UI for a rather large domain.  This application is currently in production.  However, there has been a nagging issue that I want to redress in an upcoming update.  I will speak in terms of entities, however it should be understood that these entities are ultimately backed by a SQL Server 2005 database.  

    In my domain there are entities that are changed/added/(deleted) very rarely and entities that are changed/added/(deleted) every hour, etc.  As an example, we have Shipping Methods.  In the year that the application has been in production there have probably been 3 shipping methods added and a few whose names were changed with preserved identity.  Customers would be another example, although they are midway between rarely and constantly (maybe 1 per 2 days).  Furthermore, there are many places in my application where ComboBoxes or DataGridViews are populated by these entities that infrequently change.  The approach I've used to populate these controls that display these seldom-changed entities is to load up a list for each of the different entities when the desktop application is opened.  I chose this because users move do a lot in the application (constantly opening higher-level entities and doing searches, etc.) and it would be a big drain to constantly refresh these lists every time a new order was created or loaded.

    However, this did result in a problem, because when a Customer or ShipMethod is added it is usually because someone somewhere needs to use it right then.  So, early on, I created a button that the user could click to automatically update all the lists.  I also created a mechanism by which all controls that were displaying the lists that were being updated would save their current selection, and reset their DataSource once the update was complete, then reselect their previous selection if there was one (based on an immutable ID).

    This has worked well enough, but I feel it is time to move away from this requirement that users manually update their lists, and thus why I'm posting this question.  I have come up with a scheme that could deal with this situation while still minimizing as much as possible the impact on the database (which serves not only the 40+ instances of the desktop application, but also a data driven website and some web services for order creation and the like).  I was hoping to get some feedback on this architecture:

    I would create a WCF service (lets call it AppRegistrationService) that ran on the server.  Each time the desktop application was opened it would generate a GUID and register this GUID with the app registration service.  Behind this app registration service would be an application (TableListManager, say) that either A.) monitored these entities' SQL records' timestamps every minute or so and, if it detected a change or addition (all deletes are soft deletes) run through the list of registered apps and tell them to update their lists; B.) set up triggers on the tables that would in one way or another clue the table list manager to tell the registered apps to update; C.) routed all changes to the tables through itself, then, once the transactions were completed, let the registered apps know to update their lists.

    (A) seems okay, but still requires that 20+ tables be queried every minute or so to do a difference check.  Also, it could mean a lag of up to a minute before records were updated in the registered apps (a minute that would confuse users).

    (B) is my least favorite because I don't want to bother with triggers.

    (C) seems the best to me, but requires the most work.

    If an application closed successfully (which is basically always the case) it would de-register the GUID with the app registration service.  Otherwise the app registration service would expire GUIDs after a certain length of time which would coincide with company policy for restarting the application.

    A problem I have identified would be how the app registration service notifies applications of the need to update lists.  There are several technologies I could probably use to get the message to the application.  The simplest would be to simply update a record in a database that each instance of the application checked each time before an entity is loaded or after one is cleared (IOW, before the UI is updated for loading or creating a record).  I say this would be simplest because it would avoid any threading issues, something that I have avoided in this application so far.

    So... what are people's thoughts on all of this?

     

    Thank you in advance,

    Jerome

     

    Friday, July 2, 2010 3:34 PM

Answers

  • Do you have the option to have a business server which would cache per entity?

    And.

    These 40 users.  Are they all within the 1 country and not using the application for some 8 hour period?

    Because if you do then C would be my preference.

    I'd provide the data via WCF or some process that reads data off the business server first if the data is there, out the database and caches it otherwise.  Then remove the cache when data changes.  Redo the caches as some batch job overnight.

    Any old server will do, you might want a fair bit of memory but so long as it's reasonably reliable even an xp machine would do the job.  Write the cache process so it fails gracefully.  Then if your cheap server breaks your system slows a bit but keeps on running until you go get another machine.

    Just because you have a desktop app, that doesn't stop you from using asp.net caching on the business server.

    • Marked as answer by Jeromeyers Wednesday, July 7, 2010 5:10 PM
    Friday, July 2, 2010 4:08 PM

All replies

  • Do you have the option to have a business server which would cache per entity?

    And.

    These 40 users.  Are they all within the 1 country and not using the application for some 8 hour period?

    Because if you do then C would be my preference.

    I'd provide the data via WCF or some process that reads data off the business server first if the data is there, out the database and caches it otherwise.  Then remove the cache when data changes.  Redo the caches as some batch job overnight.

    Any old server will do, you might want a fair bit of memory but so long as it's reasonably reliable even an xp machine would do the job.  Write the cache process so it fails gracefully.  Then if your cheap server breaks your system slows a bit but keeps on running until you go get another machine.

    Just because you have a desktop app, that doesn't stop you from using asp.net caching on the business server.

    • Marked as answer by Jeromeyers Wednesday, July 7, 2010 5:10 PM
    Friday, July 2, 2010 4:08 PM
  • Andy1559, Thanks for your response.  

    I wrote up a detailed response to yours and then hit the backspace key and my browser went back a page and I lost everything.  Basically, I like your suggestion.  By maintaining a master cache I can ensure that even when it is time to update a "CacheableEntity" that the database is only queried once and the separate server can serve out the data to the 40+ apps.  

    I can probably manage to code it in such a way that the separate TableListManager (TLM) classes are also included in the desktop app itself so that both apps actually use the same codebase to maintain the cache and the desktop app refreshes it's cache from the TLM and the TLM refreshes it's cache from the DB.  Therefore, if the TLM fails for whatever reason the desktop app can failover to refreshing its cache from the DB.

    I'll probably look into the caching block of EnterpriseLibrary 5.0 to see if it can fulfill the caching functionality.  I don't know much about it yet, as I only read very briefly about it the other night, but it is worth a try.

     

    Thanks for your help,

    Jeromeyers

    Friday, July 2, 2010 6:42 PM
  • The caching block is just a wrapper round asp.net cache.

    My advice would be to just use the asp.net cache.    Like I said, don't get distracted by the label asp.net.  It's a mechanism which caches objects and it'll work for winforms.

    Monday, July 5, 2010 8:35 AM
  • Andy,

    Cool, thanks, I will look into that.

    Wednesday, July 7, 2010 5:10 PM