locked
Can you tell CRM to not fire a plugin for a given SDK call? RRS feed

  • Question

  • I thought I saw an example of how to tell CRM not to fire a plugin when running some custom code. I have a web service that fires off every hour and syncs data between CRM and a legacy database. When this runs, CRM seems to get overwhelemed and the plugins will eventually crash. So if I can programmatically tell CRM that when I execute the SDK command, do not fire off any plugins, that would avoid the issue.

    I can tell the issue is the plugin, as if I disable it I do not get the error.  If I enable the plugin, it runs about 10K of records before it crashes, then the plugin crashes with a "sandbox not available error", then it seems to recover and start working again for another 10K of records.

    So it seems that maybe CRM cannot handle the volume of updates/creates I am pushing (10K in about 5 minutes) and eventually errors.  The error it throws is not within my custom code, but the default .Net code you use to access the local context.  I have commented my custom code so that all it does is hit the plugin code and does nothing.  The errors still occurs. 

    I've included the code below, but removed the code that it never gets to.  The error seems to occur when accessing the localContext.  But remember it works fine for 10K of records, crashes, then works fine again for another 10K records before crashing again.

    Any thoughts or suggestion are much appreciated.   

    namespace DHI.EntityCustomizations.Plugins
    {
        using System;
        using System.ServiceModel;
        using EntityCustomizations.Plugins;
        using Microsoft.Xrm.Sdk;
    
        /// <summary>
        /// PostContactUpdate Plugin.
        /// Fires when the following attributes are updated:
        /// All Attributes
        /// </summary>    
        public class PostContactUpdate : Plugin
        {
    
            private CrmServices _service;
    
            /// <summary>
            /// Initializes a new instance of the <see cref="PostContactUpdate"/> class.
            /// </summary>
            public PostContactUpdate()
                : base(typeof(PostContactUpdate))
            {
                base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "Update", "contact", new Action<LocalPluginContext>(ExecutePostContactUpdate)));
            }
    
            /// <summary>
            /// Executes the plug-in.
            /// </summary>
            /// <param name="localContext">The <see cref="LocalPluginContext"/> which contains the
            /// <see cref="IPluginExecutionContext"/>,
            /// <see cref="IOrganizationService"/>
            /// and <see cref="ITracingService"/>
            /// </param>
            /// <remarks>
            /// For improved performance, Microsoft Dynamics CRM caches plug-in instances.
            /// The plug-in's Execute method should be written to be stateless as the constructor
            /// is not called for every invocation of the plug-in. Also, multiple system threads
            /// could execute the plug-in at the same time. All per invocation state information
            /// is stored in the context. This means that you should not use global variables in plug-ins.
            /// </remarks>
            protected void ExecutePostContactUpdate(LocalPluginContext localContext)
            {
                
                if (localContext == null)
                {
                    throw new ArgumentNullException("localContext");
                }
    
                // Obtain the execution context from the service provider.UpdateCreateEmpowerContact
                IOrganizationService orgService = localContext.OrganizationService;
                IPluginExecutionContext context = localContext.PluginExecutionContext;
                _service = new CrmServices(orgService); // Initialize the service class.
    // It will never get here. The error seems to occur in the lines above.
            }
        }
    }


    Jon Gregory Rothlander



    Thursday, October 2, 2014 7:32 PM

All replies

  • When the plugin is registered on a message (create, update, delete, etc etc) it will always fire.

    You can enable/disable the plugins programmatically

    http://www.magnetismsolutions.com/blog/roshanmehta/2013/06/17/crm-2011-automatically-enable-disable-plug-ins-and-workflows

    but you need to know if this is suitable for your synchronization.


    My blog: www.crmanswers.net - Rockstar 365 Profile

    Thursday, October 2, 2014 7:36 PM
  • Thank Guido for the suggestion.  I had considered that, but the problem there is that I need the plugins to fire if a user is updating records, just not when the web service is doing so.  I thought I saw a way to tell CRM not to fire a plugin for a given SDK call. But I might be thinking wrong.   

    I do not want it to fire when the web service is updated/creating data in CRM, but if I user is creating or updating, I want it to fire.  I did add a text field with a record type and I set that ONLY in the web service.  So when that record type is found it skips the logic within the plugin.  But my problem is that I am getting an error trying to access the localContext and I cannot pull the record type I am sending it.  So my code is never reached when it crashes.  When it doesn't crash, that code works fine.  But when it crashes, it crashes trying to access the localContext.

    I added some sample code in my original post to show where this is occurring.


    Jon Gregory Rothlander

    Thursday, October 2, 2014 7:46 PM
  • is there any specific reason you have not made the plugin in usual way? I mean like the sdk sample? In that case, you could easily check if target contains the new field and retun if the field is not there. You can also check the context.depth to remove nested calls. I hope your base class already handle this.

    since data import, user update, web service update all invoke the same web services. Using a field to distinguish is best option.

    Thursday, October 2, 2014 9:31 PM
  • Jithesh,

    Thanks for your comments and suggestions.  I'm not sure I follow what you are saying in regards to the SDK sample.  The code I pasted above is from the auto-generate code that .Net creates for you and the code within ExecutePostContactUpdate is from the Microsoft MSDN samples. Do you have another sample that is using a different approach that you wouldn't mind sharing? Maybe that approach is a better than the one I found. 

    In my code, everything other than the following code, is auto-generated for you.  So I added the following from some Microsoft  sample I found probably 6 or 7 months ago.  It has been working fine, right up until I started having this issue recently.

    I did remove my custom code after this, as the error seems to be occurring on the code I posted.  To be specific, I have posted just that code again below.

    You mentioned using a field to distinguish when to execute certain code.  The problem there is that I never get to my custom code.  98% of the time it works fine, but occasionally the code that captures the local context (sample below) crashes.  98% of the time it does not, but out of say 80,000 records processed, I will see it crash a couple of times.  So the issue is what is causing it to crash sometimes, but not other times?  I don't know what could cause that other than CRM crashing.

                 if (localContext == null)
                {
                    throw new ArgumentNullException("localContext");
                }
                IOrganizationService orgService = localContext.OrganizationService;
                IPluginExecutionContext context = localContext.PluginExecutionContext;
                _service = new CrmServices(orgService); // Initialize the service class.


    Jon Gregory Rothlander



    Friday, October 3, 2014 1:49 PM
  • Hi,

    This could be a hardware limitation of the server i.e. non availability of sockets to create new connections or connection timeout since there are no more connections available at which point appPool is recycling it self and then able to process another 10K records and so on... 

    I would suggest you to enable tracing on MSCRM to figure out the exact problem. Also, check your event viewer to make sure that there are not obvious errors re. the services IIS / AppPool recycling etc.


    Hope this helps. Amar

    CRM Forum Guidance on how to Help Us Help You

    Friday, October 3, 2014 2:31 PM