Server Side Sync: View for Synced and Not-Synced Appointments

If you decide not to use the CRM App for Outlook, syncing emails, contacts and appointments using just Server Side Sync and Forward Mailbox can be really painful sometimes, especially when you are troubleshooting why something is not being synced. The “Server-Side Synchronization Monitoring” Dashboard provides some assistance to the Administrator, but when you want to dig into the details, I often end up using “FetchXML Builder” or “LinqPad” to query the TraceLog entity. Below is the fetchxml I use

<fetch top="50" >
  <entity name="tracelog" >
    <attribute name="tracestatus" />
    <attribute name="tracedetailxml" />
    <attribute name="tracelogid" />
    <attribute name="machinename" />
    <attribute name="tracecode" />
    <attribute name="traceactionxml" />
    <attribute name="traceparameterxml" />
    <attribute name="traceparameterhash" />
    <attribute name="errortypedisplay" />
    <attribute name="modifiedon" />
    <attribute name="text" />
    <attribute name="level" />
    <attribute name="collationlevel" />
    <filter>
      <condition attribute="tracestatus" operator="eq" value="0" />
    </filter>
    <order attribute="createdon" descending="true" />
  </entity>
</fetch>

Another common scenario that I troubleshoot is, why an appointment is not synced to Outlook after it was created in CRM. The first thing to check in this case is the user’s sync filter. I use the XrmToolBox tool “Sync Filter Manager” to check what the user’s sync filter for appointment. After confirming that the fetchxml picks up the appointment that has to be synced, we can now proceed to stage 2 of troubleshooting.

The field that is key in this scenario is called “GlobalObjectId“. This field in the appointment entity will be set, after the appointment is synced to the user’s Outlook. Unfortunately, this field is marked as not searcheable, which means it cannot be used in Advanced Find.

Global ObjectId.png

But, we can still create view that shows the synced appointments and appointments that have not been synced, using FetchXML Builder. Below are the steps

  1. Install FetchXML Builder from XrmToolBox store, if you don’t have it already
  2. Save an existing view into a new view on appointment entity. Don’t worry about the filters yet as we will update this using FetchXML BuilderSave a new view.png
  3. Next step is to open this view in FetchXML BuilderOpen View.png
  4. Update the fetchxml and save the view. Confirm the user’s sync filter for appointment using the Sync Filter Manager and make sure the new fetchxml criteria match with the user’s sync filter criteriaSave View.png

Synced Appointments – FetchXML

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
  <entity name="appointment" >
    <attribute name="subject" />
    <attribute name="scheduledstart" />
    <attribute name="scheduledend" />
    <attribute name="regardingobjectid" />
    <attribute name="prioritycode" />
    <attribute name="activityid" />
    <attribute name="instancetypecode" />
    <attribute name="location" />
    <order attribute="createdon" descending="true" />
    <filter type="and" >
      <condition attribute="scheduledstart" operator="not-null" />
      <condition attribute="instancetypecode" operator="neq" value="2" />
      <condition attribute="scheduledend" operator="not-null" />
      <condition attribute="globalobjectid" operator="not-null" />
    </filter>
    	<link-entity name="activityparty" from="activityid" to="activityid" alias="ad" >
      <filter type="and" >
        <condition attribute="participationtypemask" operator="ne" value="9" />
      </filter>
    </link-entity>
  </entity>
</fetch>

Not Synced Appointments – FetchXML

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
  <entity name="appointment" >
    <attribute name="subject" />
    <attribute name="scheduledstart" />
    <attribute name="scheduledend" />
    <attribute name="regardingobjectid" />
    <attribute name="prioritycode" />
    <attribute name="activityid" />
    <attribute name="instancetypecode" />
    <attribute name="location" />
    <order attribute="createdon" descending="true" />
    <filter type="and" >
      <condition attribute="scheduledstart" operator="not-null" />
      <condition attribute="instancetypecode" operator="neq" value="2" />
      <condition attribute="scheduledend" operator="not-null" />
      <condition attribute="globalobjectid" operator="null" />
    </filter>
    	<link-entity name="activityparty" from="activityid" to="activityid" alias="ac" >
      <filter type="and" >
        <condition attribute="participationtypemask" operator="ne" value="9" />
      </filter>
    </link-entity>
  </entity>
</fetch>

You should now be able to use these new view from the grid area.

Synced Appointments.png

If you try to use the view from Advanced Find, you will get this error.Advanced Find.png

This means you have to use FetchXML Builder to update you fetchxml, if any changes are required in the future. If you want to add more columns to the view, you’ll have to use “View Designer” to do that, as you would not be able to use Advanced Find to do this, because of this error.

I hope this post will help you troubleshoot future appointment sync issues.

Tools used:

  1. LinqPad
  2. Dynamics CRM LinqPad Driver
  3. XrmToolBox
  4. FetchXML Builder
  5. View Designer
  6. Sync Filter Manager

Server Side Sync – Polling interval

I have been battling with getting server side sync and forward mailbox working the way I want it to over the last couple of weeks. Googling hasn’t helped me a lot on this regard, and so in this post I will explain my understanding of the server side sync process.

The biggest hurdle that I faced in understanding the server side sync process is how little detail there is in the mailbox sync errors. I am not talking about the CRM Tracing, just the standard OOB logging in the application (like workflow error). Lot of times, I have seen unknown errors and mailboxes getting disabled randomly, but no detailed log in the application to indicate what the issue could be.

I used the following query in LINQPad with the CRM driver installed.

from m in MailboxSet
where m.EmailAddress == "email@email.com"
select new {
m.EmailAddress,
PostponeMailboxProcessingUntil = m.PostponeMailboxProcessingUntil.Value.ToLocalTime(),
m.ProcessedTimes,
ProcessingLastAttemptedOn = m.ProcessingLastAttemptedOn.Value.ToLocalTime(),
ReceivingPostponedUntil = m.ReceivingPostponedUntil.Value.ToLocalTime(),
PostponeSendingUntil = m.PostponeSendingUntil.Value.ToLocalTime(),
m.NoEmailCount,
m.TransientFailureCount,
m.LastSuccessfulSyncCompletedOn,
m.LastSyncError,
m.LastSyncErrorCode,
m.LastSyncErrorCount,
m.LastSyncErrorMachineName,
m.LastSyncErrorOccurredOn,
m.LastSyncStartedOn,
m.ItemsFailedForLastSync,
m.ItemsProcessedForLastSync
}

Here is a sample result.

sss

Based my tests, here is how I think it works for incoming email. The same is true for outbound emails. I am assuming that the mailboxes are not disabled and email address is approved:

  1. Async service starts to process the email at time specified in the PostponeMailboxProcessingUntil field
  2. Async service starts processing the inbound emails and creates email records in CRM
  3. In order to set the PostponeMailboxProcessingUntil and the ReceivingPostponedUntil , for the next run async service looks into the NoEmailCount field field. The NoEmailCount field is incremented every time the async service attempts to process email. If it did create some emails in CRM, the counter is reset to zero.

Based on my tests, I believe that if no email is sent/received in 15 minutes, the polling period is fixed at around 5 minutes. Here are my test results.

sss-tests

As you can see based on my tests, the polling interval gradually starts climbing when there are no emails to process and hovers around 5 minutes, after 15 minutes of inactivity i.e. no email records were created on CRM and/or no emails were sent from CRM.

If you have a queue setup in CRM, and forward an email to the queue, 5 minutes is a very long time to wait for the async service to pickup the email from Exchange. I saw couple of posts about how this polling interval can be changed by modifying the “Minimum Polling Interval” field.

polling-interval

The recommended value for this field is “0” and even when I changed this to 1 minute, I haven’t seen it influence the “ProcessingLastAttemptedOn“. I tried to change “PostponeMailboxProcessingUntil” and “ReceivingPostponedUntil” for the mailbox though the SDK, but since they are readonly fields, they cannot be changed. All the tests were carried out in OnPrem CRM2015, and so I cannot confirm whether this is the same behaviour in CRM2016 or Dynamics 365.

EDIT (18/11/2016): This 5 minute polling interval seems to be a “by-design” behavior. Thank you Andre Margono for sending this info. Here is what the MSDN article says:

When synchronization by using server-side synchronization occurs, the process is dynamic and unique for each user’s mailbox. The synchronization algorithm ensures that mailboxes are synced according to dynamic parameters such as the number of email messages and the activity within the mailbox. Normally, email synchronization occurs every 5 minutes. When a mailbox has many email messages, the interval can be reduced dynamically to 2 minutes. If the mailbox is less active, the interval can be increased up to 12 minutes. Generally speaking, you can assume that a mailbox will be synced at least once every 12 minutes. Note that you can’t manually synchronize records through server-side synchronization and when you track email (Track button), this occurs immediately.

tl;dr; If your CRM application is not processing any email (sending/receiving) in 15 minutes, the polling interval will eventually be fixed at around 5 minutes. When an email is received, async service will start processing more frequently, but the polling period will slowly climb with no-activity until it gets to 5 minutes.