WCF PerCall instance State Aware

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • centrifugal
    New Member
    • Nov 2009
    • 2

    WCF PerCall instance State Aware

    Hi,

    I am in the process of converting an Oracle forms application to Asp.Net. Currently I am using a WCF web service to manage all of my Oracle database calls and to convert the data in to business objects. The business objects can then be easily consumed by the Asp.Net application. All of this works fine.

    The problem I am having is with performance on the service. Since my instancing mode is per call the webservice needs to recreate the state/security object on every call. The state object includes a database connection, security parameters, and various other values that are required to set the users context.

    Based on what I have read the best way to accomplish this is to store the state objects in memory/static variable and to provide some sort of reference to the client that it can use on each service call. I understand that memory is volatile and can be recycled for various reasons in IIS, this is fine since the data in question is not important and can be regenerated. The objects to be stored are not that large, but they are created from several complex queries, and doing this on each service call is very expensive.

    Can someone give me some code examples of the best method of storing this data in memory on the web service?

    Thanks
  • cloud255
    Recognized Expert Contributor
    • Jun 2008
    • 427

    #2
    What I usually do is create a server side cache to store these instances. Upon authentication I send a unique ID back to the client machine, this ID is then used upon each request to the server. Note that this ID should be more complex than just an integer for security reasons. A hash value or some sort of randomly generated string works well.

    User data is stored in a dictionary which the server uses for lookups, the unique ID being the key of the dictionary. The issues with this approach is that you need to build in some sort of timeout mechanism, which invalidates the ID on the server side and removes the entry from the dictionary, thus freeing memory. A simple way to do this is to add a time stamp to the dataobject held by the dictionary, this time stamp represents the last time the client sent a request to the server. I then have a thread which runs every x minutes checking the time span from the last last client activity and removes all expired entries.

    On another note the database connection information is generally stored in a data access layer which is independent of the state/security objects. The data access layer has several exposed methods allowing clients to access data and stored procedures. This allows one to only pass an enumeration to said method representing the user's authority level. The function can then internally check if the user has rights to execute it. This approach works well when you define several user roles within the system with respects to access privileges.

    Hope this helps

    P.S. What I described above is how I code our client/server application, things may vary slightly in a web based environment. My knowledge of web programming is not nearly enough to be sure which aspects may differ.

    Comment

    • centrifugal
      New Member
      • Nov 2009
      • 2

      #3
      Initially I had designed the data access layer to be completely seperate from the business services. The issue I am facing is that since it is currently an Oracle forms application, all of the application login accounts are actually Oracle database accounts and their permissions are managed by the builtin roles table. I need both applications to continue working concurrently until the new application has been completed. So what I have done as a work around is added the db connection to the state object which it can pass in to the data access layer.

      Anyway going back to the original issue, thanks for your reply it has reassured me on alot of things. I think I am headed in the right direction now. I am still a bit confused as to how to actually code in this static dictionairy to contain all of the state objects. In my most recent attempt I created a static class with static list and it stills seems to be cleared/recycled quite frequently. I can never get more than 10 objects into the list before it is cleared and even when I try to retrieve information back it is never valid. I verified my IIS settings are set to recycle once a day at 3am.

      I believe it has something to do with my instancing mode being per call, although I am not experienced enough with WCF to know for sure. Are there any special workarounds I need to implement so that I can persist static variables for the lifetime of the application?

      Thanks

      Comment

      • cloud255
        Recognized Expert Contributor
        • Jun 2008
        • 427

        #4
        Have a look at the singleton approach and inversion of control this is useful when creating and managing services. A user state service might be the solution to your problem.

        Also check to see if your list/dictionary is being garbage collected, have a look at the KeepAlive method of the garbage collector. You may use this method to prevent the garbage collector from removing a reference from memory. Remember that if you have no references to a variable the garbage collector will dispose of the object.

        P.S. If your problem persists, post the code which you use to read and add data to your list and we'll have a look at it.

        Comment

        Working...