CRM plugin registered in "synchronous" execution mode and in "Post operation" in Eventing execution staging

질문 CRM plugin registered in "synchronous" execution mode and in "Post operation" in Eventing execution staging

  • 2012년 6월 28일 목요일 오후 6:29
     
     

    Hi 

    I am unsure about how synchronous versus asynchronous execution happens. 

    Here is scenario

    1. Plugin has been registered in "synchronous" execution mode and in "post operation" in Eventing pipeline stage of execution. 

    2. There was an update event fired for an entity.

    2. Does the entity gets saved in CRM first and then plugin gets called or Plugin gets invoked first and after plugin is finished doing stuff, entity gets saved in CRM?

    Your help would be highly appreciated.

    Thanks


    navighag

모든 응답

  • 2012년 6월 28일 목요일 오후 6:50
     
     

    Firstly. Synchronous plugins run in the IIS process (w3wp.exe) and Asynchronous plugins run in the  CrmAsyncService process. When registered in Synchronous mode, your transaction is blocked until the plugin code is finished, in Asynchronous mode, your the plugin is running in non-block fashion so the rest of operation doesn't have to wait for the plugin code to finish running.

    Since you registered your plugin in "post operation", I would say that your entity has been saved before the plugin is called. But still your UI will be blocked (IE no responsive) until your plugin code finish running.

    Hope this helps.

     
  • 2012년 6월 28일 목요일 오후 7:12
     
     

    Hi Navighag,

    In CRM 2011 Synchronous plugins the are blocking any operation i.e. Until Synchronous plugin does not completes operation does not completes itself. Also Synchronous plugin both pre and post run under same transaction as the operation (trigging operation like create/update/delete) i.e. if the plugin pre or post plugin fails (due to an exception) nothing is committed to CRM database. So the good places to use them will to use them where you have to do things in a transaction like moving money from one bank account to another (if any thing goes wrong nothing should be saved.)

    On the other hand asynchronous does not execute in any transaction boundary i.e. if this plugin fails the parent operation (trigging operation like create/update/delete) will not be effected. 

    http://social.microsoft.com/Forums/eu/crmdevelopment/thread/317a9616-4104-4ebc-bdb6-ffef406c1d45


    -Devashish
    http://thecrmworld.wordpress.com
    http://ebizartisans.com

  • 2012년 6월 28일 목요일 오후 7:16
     
     

    Thanks Wei Ma.

    But here is what i am observing

    So whenever my plugin gets fired for an update of an entity, 

    1. I check for a particular field in received entity, If it is "false" then return. Otherwise("true"), plugin does it stuff and finally set this field to false and updates the record.

    2. Why i need to set this filed to false : So CRM record can be updated in 2 ways, on from CRM forms and other is our application pushing data to CRM. 

    3. So when i have registered plugin "Synchronous" and in "Post operation" , then it goes in an infinite loop which means that that particular boolean field was not set to false. 

    4. But if i register plugin in "asynchronous" execution mode, it does not go into infinite loop.

    Please correct me if i am wrong, the object(with value "false" (updated from plugin itself) ) got overwritten by the very first call which invoked plugin.

    Please share your thoughts.


    navighag

  • 2012년 6월 28일 목요일 오후 7:24
     
     

    Hi Navighag,

    The problem is in your code if you will update the same entity with a service call the same plugin will be fired again and this will go into infinite loop as you mention above.

    If you want to update some field using your plugin please register a pre state plugin and dont use service call rather use something lile following

    if(!EntityBeingUpdate.Contains("YourBooleanEntity"))

    {

    EntityBeingUpdate["YourBooleanEntity"] = true;

    }

    // and let the plugin go.

    Post plugin CRM will update the entity (in this case EntityBeingUpdate) and as you have added your attribute "YourBooleanEntity" it will also be saved.

    Hope it helps.


    -Devashish
    http://thecrmworld.wordpress.com
    http://ebizartisans.com

  • 2012년 6월 28일 목요일 오후 7:25
     
     

    Do you have a code snippet that can share? I am suspecting the 

    context.Update() failed when registered in Synchronized mode. But without code, I can't make much analysis.

  • 2012년 6월 28일 목요일 오후 7:26
     
     

    I have added the logic to check depth property, It will return if it is greater that 1. So that is not causing infinite loop.


    navighag

  • 2012년 6월 28일 목요일 오후 7:29
     
     

    If possible please add your code to your post.


    -Devashish
    http://thecrmworld.wordpress.com
    http://ebizartisans.com

  • 2012년 6월 28일 목요일 오후 7:30
     
     
    Checking the depth will prevent infinite recursive call. But I thought you had a loop somewhere in your code.  
  • 2012년 6월 28일 목요일 오후 7:34
     
     

    @Wei Ma

                     

     if (localcontext.PluginExecutionContext.MessageName == "Update" || localcontext.PluginExecutionContext.MessageName == "Create")
                    {
                        if (received.LogicalName == "new_myEntity")
                        {
                             if (localcontext.PluginExecutionContext.MessageName == "Update")
                            {
                                entityCRM = service.Retrieve(received.LogicalName, received.Id, cols).ToEntity<New_myEntity>();
                            }
                            else
                            {
                                entityCRM = received.ToEntity<New_myEntity();
                            }
                            if (entityCRM.New_isusermodified != true || entityCRM.New_isusermodified == null)
                            {
                                  return;
                            }
                            else
                            {
                                entityCRM.New_isusermodified = false;
                                service.Update(entityCRM);

                            }

                      }
                    }

    Note: Depth property is checked each time plugin gets invoked. If it is greater than 1 then return.


    navighag

  • 2012년 6월 28일 목요일 오후 7:42
     
     

    Yes ...because the CRM record can be updated in 2 ways. One from CRM itself, and other is the backend application pushing data to CRM. 

    So i need to differentiate which resource is calling the update of CRM reocrd. So i have new_isusermodified filed, which is set to true in java script when that entity's form get loaded. Now i set it to false in plugin and update the record by saying service.update(record).  

    So when i do it synchronously then, it goes not an infinite loop , which means the boolean var never got set to false.  and it goes into an infinite loop.

    and if i do it asynchronously, then it does not go into an infinite loop. 


    navighag

  • 2012년 6월 28일 목요일 오후 7:50
     
     

    Just by checking your code did not find any logic error. However, I just came across this post http://social.microsoft.com/Forums/fi-FI/crmdevelopment/thread/c8e5f6b3-7bea-4a00-a36b-27c39603f47a

     seems that because you registered as post operation, so the Update was ignored.

  • 2012년 6월 28일 목요일 오후 7:56
     
     

    Yes ...because the CRM record can be updated in 2 ways. One from CRM itself, and other is the backend application pushing data to CRM. 

    So i need to differentiate which resource is calling the update of CRM reocrd. So i have new_isusermodified filed, which is set to true in java script when that entity's form get loaded. Now i set it to false in plugin and update the record by saying service.update(record).  

    So when i do it synchronously then, it goes not an infinite loop , which means the boolean var never got set to false.  and it goes into an infinite loop.

    and if i do it asynchronously, then it does not go into an infinite loop. 


    navighag

    Actually, I think you can remove your new_isusermodified property all together when you have Depth check to safeguard.
  • 2012년 6월 28일 목요일 오후 8:03
     
     
    I want new_isusermodified because in case it gets fired from the application (in which case it is false) . In this case depth property will be less than 1 so plugin will get invoked and we do not want that.

    navighag

  • 2012년 6월 28일 목요일 오후 8:07
     
     
    Just out of curiosity you can get this working with a pre-state plugin without this problem and reducing a service call for update (which will be is faster) but you dont want to do it because you want to find the problem in this case for your learning correct

    -Devashish
    http://thecrmworld.wordpress.com
    http://ebizartisans.com


  • 2012년 6월 28일 목요일 오후 8:07
     
     

    @ Wei Ma

    i went through the link that you sent http://social.microsoft.com/Forums/fi-FI/crmdevelopment/thread/c8e5f6b3-7bea-4a00-a36b-27c39603f47a

    The answer says

    "This issue was discussed at forum billion times. You plugin fires but it doesn't execute any update because you've registered it at post-operation mode (after db operations are already executed). To make it work you should register it to work in Pre-Operation mode (before DB operations are executed) or rewrite your plugin to update record using Update method but in this case you should check depth property of context."

    So i am using service.Update . So its should work.


    navighag

  • 2012년 6월 28일 목요일 오후 8:15
     
     
    Yes. And you did the depth check. So, you are doing the right thing.