Two key aspects to S4S performance are keeping the Salesforce session alive and ensuring new sessions are not established for each API call to Salesforce. For the former, S4S will re-establish session automatically if it times out but the same session needs to be used for successive calls to stop S4S creating multiple new sessions, and taking up to four API calls to do this.
When in ASP.NET you will most likely create the SalesforceSession using credentials stored in a connection string. In the simplest case this would be:
SalesforceSession salesforceSession = new SalesforceSession("connectionStringName");
This will work but if you call Salesforce frequently it is better to keep calling the same session as, in most cases, it will be kept alive. You could do this either via the ASP.NET Cache or the SalesforceSessionSingleton base class that is part of S4S. It has a number of constructors.
If using the ASP.NET cache store the SalesforceSession in the IIS Application cache not the Session cache.
If using S4S please consider the following code snippet:
/// /// Singleton Pattern returns a SalesforceSession instance created with S4SConnStringUI connection string /// public class SitecoreSalesforceSessionSingleton : SalesforceSessionSingleton { private SitecoreSalesforceSessionSingleton() : base(null, "connectionStringName") { } /// /// Get the singleton instance of the Salesforce Session. /// public static SalesforceSession SessionInstance { get { SitecoreSalesforceSessionSingleton singleton = new SitecoreSalesforceSessionSingleton(); return singleton.Instance; } set { SitecoreSalesforceSessionSingleton singleton = new SitecoreSalesforceSessionSingleton(); singleton.SetNewInstance(value); } } }
When you need a SalesforceSession you make the following call instead:
SalesforceSession salesforceSession = SitecoreSalesforceSessionSingleton.SessionInstance;
The preferred way to handle expired sessions when using a connection string is with the autoReestablishSession parameter on the SalesforceSession constructor overload e.g. where connectionStringName is a string.
_instance = new SalesforceSession(connectionStringName, true);
The code sample below will handle the first session expiration. The subsequent instance won’t be connected to the OnInvalidSession event.
Note that we also provide the SalesforceSessionSingleton abstract class if you want to use that as the base of your singleton implementation. It provides the locking object and a volatile static to store the session instance. Sample implementation:
class TestSalesforceSessionSingleton : SalesforceSessionSingleton { static string connectionStringName = "S4SConnString"; private TestSalesforceSessionSingleton() : base(new LoginDetails("designTimeUser@fuseit.com", "passwordForDesignTimeConnection"), connectionStringName) { // The LoginDetails in the first parameter are only used at DesignTime, can be null if not needed. } /// /// The singleton instance of the Salesforce Session. /// public static SalesforceSession SessionInstance { get { TestSalesforceSessionSingleton singleton = new TestSalesforceSessionSingleton(); return singleton.Instance; } set { // This is only required if you want code outside the singleton to be able to construct the session TestSalesforceSessionSingleton singleton = new TestSalesforceSessionSingleton(); singleton.SetNewInstance(value); } } }
If you cannot achieve the required performance you can sync selected Salesforce data to a MongoDB database using our M4S connector.
Comments
2 comments
I'm using this sample code above to retrieve the Sales Force Session from SitecoreSalesforceSessionSingleton class. This works great if you're constantly submitting leads to Sales Force. However, if the website just came up for the first time (clean slate), the first end user will not benefit from a cached SalesForceSession and the submission will take around 10 - 12 seconds. Is there a technique to pre-cache the SalesForceSession object when the website first comes up? I tried doing this in the Global.ASCX in Application.Start() but I get an error message from the S4S connector saying:
Mike, thanks for going ahead and creating a proof of concept for us.
To always keep the Salesforce session alive the preferred solution is to create a custom Sitecore page that only exists to maintain Salesforce session as per the FAQ Answer. The new custom.aspx page is periodically refreshed with a Sitecore UrlAgent scheduled event configured in web.config.
The problem is that the custom.aspx page only gets called after the first period of time has elapsed. If the website restarts there is an initial delay before the Salesforce session is established.
The solution is to create a custom processor in the initialize section of web.config (see SalesforceSessionInitializer processor below). The custom processor class spawns a new worker thread that makes a web request to the custom.aspx page. A new thread is required otherwise Sitecore will stop and wait indefinitely for a response.
<!-- PIPELINES -->
<pipelines>
<initialize>
<processor type="Sitecore.Pipelines.Loader.ShowVersion, Sitecore.Kernel">
<assemblies hint="list:AddAssembly">
<assembly>/bin/Sitecore.Client.dll</assembly>
<assembly>/bin/Sitecore.Kernel.dll</assembly>
<assembly>/bin/Sitecore.Nexus.dll</assembly>
</assemblies>
<showDatabases>true</showDatabases>
<showDomains>true</showDomains>
<showDebugWarning>true</showDebugWarning>
</processor>
<processor type="Sitecore.Pipelines.Loader.ShowHistory, Sitecore.Kernel"/>
.
.
<processor type="FuseIT.Web.UI.Pipeline.SalesforceSessionInitializer, FuseIT.Web.UI"/>
</initialize>
Please sign in to leave a comment.