1. #201
    Sencha User
    Join Date
    Jan 2010
    Posts
    8
    Vote Rating
    0
    codeable is on a distinguished road

      0  

    Default re: Cache Problem

    re: Cache Problem


    I too ran into that caching problem, but instead of "fixing" it, I changed it to raise a more meaningful exception. In my environment, if the application is restarted then all consumers of that particular provider must fetch a new one from the server. (by responding to the exception).

    It seems to me that your environment allows for recompile without app restart. (you are using debug builds and/or debug='true'?) So it recompiles part of the website (but leaves Ext.Direct [and others] alone) and continues on. So you get some old and some new assemblies running together. And anything that uses static caching (like the ProviderCache) will have data, while the session/application based caches may not.

    Just my two pennies.

  2. #202
    Ext JS Premium Member
    Join Date
    Aug 2009
    Posts
    112
    Vote Rating
    1
    Whatty is on a distinguished road

      0  

    Default


    We also ran into this problem and it was related to the IIS application domain being recycled.


    There are some known events which cause the application domain to be recycled (search google for complete results) but some of them are
    • memory usage
    • web.config being changed
    • structural changes to the site (i.e. adding or removing a directory)
    Due to the nature in which the API handler creates the cache entrys if the application domain is recycled between the call the API handler and the next call the DirectHandler you will get a cache of zero. In our case were we dynamically creating an optimized page JS file which added a directory to the site and caused the APP_DOMAIN to be recycled.

    You can verify this by outputting the APP_DOMAIN ID in the APIHandler request

    Code:
    log.Debug("ApiHandler processing request for session (" + context.Session.SessionID + ") in application domain: " + Thread.GetDomain().FriendlyName);
    and the DirectHandler Request

    Code:
    log.Debug("DirectHandler processing " + context.Request.RequestType + " request for session (" + context.Session.SessionID + "): prinicpal \"" + Thread.CurrentPrincipal.Identity.Name + "\" in application domain: " + Thread.GetDomain().FriendlyName);
    If the APP_DOMAIN ID has changed between calls then your APP DOMAIN got recycled.

    Other post have mentioned to catch this situation and recreate the cache which is a viable solution.

    Whatty




    Quote Originally Posted by Seana View Post
    I maybe doing something wrong, or it maybe that IIS/Cassini are in cahoots to drive me a touch insane, but it seems that after a random allotment of time the DirectProviderCache is being blown away. It seems related to the same issue as...


    Found here

    The actual issue is that some indeterminate time interval after starting the application when making an Ext.Direct call (via a store or manual invocation) I would be presented with a KeyNotFoundException on Line 50 of DirectHandler.CS more specifically

    Code:
    provider = cache[this.ProviderName];
    When seeing this while the debugger was attached (either to Cassini or IIS7) the cache always has a size of 0. The final technical piece that made me think this may in fact be related to the above quoted forum post was while actively attempting to catch the exception "in the wild" I noticed that Cassini reloaded all the assemblies upon the calling of the direct method that caused the exception, looking very much like it was effectively purging the memory used by the web server handling the app.


    So I suppose my first question is, is this automatic cache/memory pruning a possibility or am I possibly doing something wrong and it's just manifesting itself in a similar manner?

    I'm thinking should it be that this is in fact an IIS/Cassini behavior, handling it should be as simple as adding an "else if(cache.Count() == 0)" control structure at line 48 of DirectHandler.cs...


    Sean

  3. #203
    Sencha User Seana's Avatar
    Join Date
    Jun 2010
    Posts
    82
    Vote Rating
    0
    Seana is on a distinguished road

      0  

    Default


    Quote Originally Posted by Whatty View Post
    We also ran into this problem and it was related to the IIS application domain being recycled.


    There are some known events which cause the application domain to be recycled (search google for complete results) but some of them are
    • memory usage
    • web.config being changed
    • structural changes to the site (i.e. adding or removing a directory)
    Due to the nature in which the API handler creates the cache entrys if the application domain is recycled between the call the API handler and the next call the DirectHandler you will get a cache of zero. In our case were we dynamically creating an optimized page JS file which added a directory to the site and caused the APP_DOMAIN to be recycled.

    You can verify this by outputting the APP_DOMAIN ID in the APIHandler request

    Code:
    log.Debug("ApiHandler processing request for session (" + context.Session.SessionID + ") in application domain: " + Thread.GetDomain().FriendlyName);
    and the DirectHandler Request

    Code:
    log.Debug("DirectHandler processing " + context.Request.RequestType + " request for session (" + context.Session.SessionID + "): prinicpal \"" + Thread.CurrentPrincipal.Identity.Name + "\" in application domain: " + Thread.GetDomain().FriendlyName);
    If the APP_DOMAIN ID has changed between calls then your APP DOMAIN got recycled.

    Other post have mentioned to catch this situation and recreate the cache which is a viable solution.

    Whatty
    This was indeed the case, it had nothing to do with code changes or in place recompiling. While I agree with Codeable about "asking" for a re-cache on the client side being a viable solution, the Library out of the box does not afford this option thus I thought it worth mentioning in the official thread. The change as Evan had posted has worked quite well over the past 2 weeks.

    I meant to say so sooner, however have had very little "computer time" since the birth of my son... speaking of which it is time for more coffee
    Sean

  4. #204
    Ext User
    Join Date
    Jun 2008
    Posts
    10
    Vote Rating
    0
    angel.ignacio.colmenares is on a distinguished road

      0  

    Default


    Ext.Direct.Net + ext 3.3.0

    Running CRUD Samples - Create produces

    "Uncaught TypeError: Cannot read property 'length' of undefined"

    after saving new record, new record is marked in grid as 'dirty' but it really saved in db

  5. #205
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    909
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    Looking to use Ext.Direct now we're upgrading from Ext 2.2 so thanks for this stack Evan
    Looks like it'll meet my needs nicely.

    Used to use Jayrock with 2.2 and this Ext.Direct stuff looks pretty similar.

    Hope it supports nullable types, if not I'll make it do so

    Cheers,
    Westy


    Edit:
    Hehe, like the 'deliberate' bug in Echo Time sample... thought I was going mad for a second:
    Code:
    var s = String.format('The current date/time is: <b>{0}</b>', data.format('Y-m-d H:s'));

  6. #206
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    909
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default A little tweak

    A little tweak


    Hi,

    Started putting together some standards for our web services, and started playing around with this stack again whilst testing dual interfaces to some of our services (i.e. SOAP and Ext.Direct).

    A few suggestions, if I may?
    1. Add the constructor to DirectException that takes an innerException.
    2. In the DirectProvider.Execute, change the exception handler to use that constructor.
      i.e. throw new DirectException("Error occurred while calling Direct method.", ex);
    3. In DirectProcessor.ProcessRequest, change:
      r.ExceptionMessage = (ex.InnerException != null) ? ex.ToString() : ex.Message;

    That's it for now.

    I have changed my local copy, but am hoping that this stack is still maintained.
    If not then I'll may take it on I suppose, and provide a slightly more defensive implementation (i.e. that expects the worst).

    Cheers,
    Westy

  7. #207
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    909
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    Can't seem to edit my post, guess still some kinks in the shiny new forum (which looks great btw).

    Wsa just gonna add that this improves the exceptions you get back to the client from the web service, rather than always being "An error was thrown by the target of the invocation" type things.

    Cheers,
    Westy

  8. #208
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    909
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    Another update...

    Was shocked to find that if a direct method takes an object as a parameter no conversion is attempted from the JSON passed up. It just tries to make the call passing the dictionary.

    I've tried to solve this, by putting the following before the method invocation in DirectProvider.Execute:
    Code:
    // If any of the parameters of the method we are calling are classes
    // we need to try and create our instances from our Dictionary.
    var methodParams = method.Method.GetParameters();
    
    int i = 0;
    foreach (ParameterInfo methodParam in methodParams)
    {
        // FIXME: If want to support interfaces as parameters will need an attribute
        // .....: to give us the class instance to create or something...
        if (!methodParam.IsOut && methodParam.ParameterType.IsClass)
        {
            // Check that our corresponding parameter is a dictionary
            if (!typeof(System.Collections.IDictionary).IsAssignableFrom(param[i].GetType()))
            {
                throw new DirectException(String.Format("Parameter '{0}' should be a JSON object, since needs to be converted to a class instance.", i));
            }
    
            // We need an instance of our class
            var ctr = methodParam.ParameterType.GetConstructor(System.Type.EmptyTypes);
            if (ctr != null)
            {
                var instance = ctr.Invoke(null);
                
                // Now attempt to copy our values in
                System.Collections.IDictionary dic = (System.Collections.IDictionary)param[i];
                foreach (System.Collections.DictionaryEntry entry in dic)
                {
                    // Try and find property our class
    
                    // Need to make first letter upper-case to match C# conventions
                    string propName = entry.Key.ToString();
                    propName = propName.Substring(0, 1).ToUpperInvariant() + propName.Substring(1);
                    
                    var prop = methodParam.ParameterType.GetProperty(propName);
                    if (prop == null)
                    {
                        throw new DirectException(String.Format("Parameter '{0}' contains a value '{1}' that is not in the class that is on the methods interface.", i, entry.Key));
                    }
    
                    var propSet = prop.GetSetMethod();
                    if (propSet == null)
                    {
                        throw new DirectException(String.Format("Parameter '{0}' contains a value '{1}' that has no public property setter in the class that is on the methods interface.", i, entry.Key));
                    }
    
                    // Set property value
                    propSet.Invoke(instance, new object[] { entry.Value });
                }
    
                // Now overwrite our parameter with our class instance
                param[i] = instance;
            }
        }
    
        ++i;
    }

    Another update expected in a bit, since am getting no result success element when returning null or an empty collection...

    Evan, how would you feel about me firming up some of this router and posting it on a public repo somewhere?

    Cheers,
    Westy


    Edit:
    I can't help but think I'm missing something here.

    If my object is marked with the JsonObject attribute, and the properties suitably marked with JsonProperty attributes, shouldn't JSON.Net just sort this?

    Why isn't it?
    Are you meant to hand write a JsonConverter instance for each type? Find that hard to believe given those attributes...

  9. #209
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    909
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    Hi again.

    Ok, I was missing something with my above solution, but so crucially was this router.

    I believe I have sorted it, by doing the following:
    1. Removing ComplexObjectConverter attribute from DirectRequest.Data so that all passed objects appear as JsonObject's (can't see what the dictionary was for to be honest).
    2. Removing ParseAsJson attribute since not needed.
    3. Updating DirectProvider to inspect the parameters of the function it has to call; if any have the JsonObject attribute on them then that parameter is deserialized using JSON.Net.

    I've also used to opportunity to update the router to use JSON.Net 3.5 r8, which required a tweak to the deserialization of DirectRequest's.

    I intend to clean up what I've done when I get the chance and post it somewhere if ok with Evan; have more pressing matters at present though, so may have to wait a while...

    Cheers,
    Westy

  10. #210
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,920
    Vote Rating
    632
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    I'll setup a github repo. PM your nick!
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!