Solving asynchronous Event Handler update conflicts

Titus makes truly great and unique software for securing SharePoint documents based on metadata.   However I ran into a huge problem.  Some document uploads produced an error seemingly at random.  Reducing the number of documents, metadata fields, and content types had no effect.  This problem occurred in three totally separate farms and took way too long to solve, but a solution was indeed found by Titus, and was infuriatingly simple.  First some basics.

SharePoint supports both “Before” events and “After” events. Before events are raised when a specified action occurs before SharePoint writes to the content database, these are “ing” events, such as ItemAdding, these are always “Synchronous” as these are commonly used for custom validation where an event handler can cancel the “Adding” of an item.

First a definition on synchronous vs asynchronous.  A synchronous call is one in which the caller pauses and waits for a response.  An asynchronous call is one in which the caller continues without pausing for a response.  This allows both the caller and the method being called to execute at the same time.

To put a fine point on it, Before events such as ItemAdding are always supposed to be Synchronous, and this Titus event handler is apparently by default Asynchronous, hence our random problem.

The solution is to just make sure one of the Titus Event Handlers is set to process as “Synchronous”.   I took the Titus folk’s advice, and wrote the script below which loops through all libraries, and notes their “synchronicity” (I couldn’t resist that) and fixes any that are out of whack.

$url = "http ://sharepoint/sites/yourSite;$contextSite" = New-Object Microsoft.SharePoint.SPSite($url);
$contextWeb = $contextSite.OpenWeb();
 for ($LibIndex=0; $LibIndex -lt $contextweb.Lists.Count; $LibIndex++)
{
    $list = $contextWeb.Lists[$LibIndex];
    $i=-1;
    $ERtoUpdate=$null;
    foreach ($ER in $list.EventReceivers)
    {
         #write-host "Event $($i): $($ER.name)"
         $i++
         if ( $ER.name -eq "TITUS Security Suite for Sharepoint ItemAdded")
         {
             if ($ERtoUpdate -ne $null)
             {
             write-host "DUPLICATE TITUS EVENT RECEIVER FOUND: Event $($i): $($ERtoUpdate.name) changes to Synchronous for $($list.title)"
             }
             else
             {
             $ERtoUpdate=$ER;
             $eventNum=$i;
             }
         }
    }
    if ($ERtoUpdate -ne $null)
    {
         if ($ERtoUpdate.Synchronization -eq 1)
         {
             write-host "TITUS event handler was already set to Synchronous for Event $($eventNum): $($ERtoUpdate.name)for  $($list.title)" -ForegroundColor DarkGreen
         }
         else
         {
             $ERtoUpdate.Synchronization=1;
             write-host "Event $($eventNum): $($ERtoUpdate.name) changes to Synchronous for $($list.title)"
             $ERtoUpdate.Synchronization=1;
             $ERtoUpdate.Update();
             $list.Update()
             }
    }
    else
    {
         write-host "TITUS event handler not found for Event $($eventNum): $($ERtoUpdate.name) changes to Synchronous for $($list.title)" -ForegroundColor DarkGreen
    }
}
$contextWeb.Update()
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *