Home » Link Database
Category Archives: Link Database
Periodically Rebuild Link Databases using an Agent in Sitecore
Last week a colleague had asked me whether rebuilding the Link Database would solve an issue she was seeing. That conversation got me thinking: wouldn’t it be nice if we could automate the rebuilding of the Link Database for each Sitecore database at a scheduled time?
I am certain others have already created solutions to do this — if you know of any, please share in a comment — but I didn’t conduct a search to find any (I normally advocate not reinventing the wheel for code solutions but wanted to have some fun building a new solution).
In the spirit of my post on putting Sitecore to work for you, I built the following Sitecore agent (check out John West’s blog post on Sitecore agents to learn more):
using System; using System.Collections.Generic; using System.Diagnostics; using System.Xml; using Sitecore.Configuration; using Sitecore.Data; using Sitecore.Diagnostics; using Sitecore.Jobs; namespace Sitecore.Sandbox.Tasks { public class RebuildLinkDatabasesAgent { private static readonly IList<Database> Databases = new List<Database>(); private static readonly Stopwatch Stopwatch = Stopwatch.StartNew(); public void Run() { JobManager.Start(CreateNewJobOptions()); } protected virtual JobOptions CreateNewJobOptions() { return new JobOptions("RebuildLinkDatabasesAgent", "index", Context.Site.Name, this, "RebuildLinkDatabases"); } protected virtual void RebuildLinkDatabases() { Job job = Context.Job; try { RebuildLinkDatabases(Databases); } catch (Exception ex) { job.Status.Failed = true; job.Status.Messages.Add(ex.ToString()); } job.Status.State = JobState.Finished; } private void RebuildLinkDatabases(IEnumerable<Database> databases) { Assert.ArgumentNotNull(databases, "databases"); foreach (Database database in databases) { Stopwatch.Start(); RebuildLinkDatabase(database); Stopwatch.Stop(); LogEntry(database, Stopwatch.Elapsed.Milliseconds); } } protected virtual void RebuildLinkDatabase(Database database) { Assert.ArgumentNotNull(database, "database"); Globals.LinkDatabase.Rebuild(database); } protected virtual void LogEntry(Database database, int elapsedMilliseconds) { Assert.ArgumentNotNull(database, "database"); if (string.IsNullOrWhiteSpace(LogEntryFormat)) { return; } Log.Info(string.Format(LogEntryFormat, database.Name, elapsedMilliseconds), this); } private static void AddDatabase(XmlNode configNode) { if (configNode == null || string.IsNullOrWhiteSpace(configNode.InnerText)) { return; } Database database = TryGetDatabase(configNode.InnerText); if (database != null) { Databases.Add(database); } } private static Database TryGetDatabase(string databaseName) { Assert.ArgumentNotNullOrEmpty(databaseName, "databaseName"); try { return Factory.GetDatabase(databaseName); } catch (Exception ex) { Type agentType = typeof(RebuildLinkDatabasesAgent); Log.Error(agentType.ToString(), ex, agentType); } return null; } private string LogEntryFormat { get; set; } } }
Logic in the class above reads in a list of databases set in a configuration file, adds them to a list for processing — these are only added to the list if they exist — and rebuilds the Link Database in each via a Sitecore job.
I added some timing logic to see how long it takes to rebuild each database, and capture this information in the Sitecore log.
I then wired up the above class in Sitecore using the following patch include configuration file:
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <scheduling> <agent type="Sitecore.Sandbox.Tasks.RebuildLinkDatabasesAgent" method="Run" interval="00:01:00"> <databases hint="raw:AddDatabase"> <database>core</database> <database>master</database> <database>web</database> </databases> <LogEntryFormat>Rebuilt link database: {0} in {1} milliseconds.</LogEntryFormat> </agent> </scheduling> </sitecore> </configuration>
I’ve set this agent to run every minute for testing, but it would probably be wise to have this run no more than once or twice a day.
After waiting a bit, I saw the following in my Sitecore log:
I do question the rebuild times. These seem quite small, especially when it takes a while to rebuild the Link Databases via the Sitecore Control Panel. If you have any ideas/thoughts on why there is an incongruence between the times in my log and how long it takes to rebuild these via the Sitecore Control Panel, please share in a comment.
Further, if you have any recommendations on making this code better, or have other ideas on automating the rebuilding of Link Databases in Sitecore, please drop a comment.
Until next time, have a Sitecoretastic day!