Imagine a site with 10+ instances and a lot of visitors and search requests. The find queries are tracked, to provide data for the auto suggest, and cached.
And then… you get an error in Find: Too Many Requests.
My first thought was to increase the value for StaticallyCacheFor. But it did not have as much of an impact as I thought. After looking into how the queries are cached I found that it is cached per server/instance. So when you have 10+ instances… it does not help much. You can’t override the ICache implementation, so I have put in a feature request for that.
The next thing I noticed was that for each request that was done to Find, another one was done for the tracking. Disabling tracking was not really an option, as that would cripple the auto suggest.
So I came up with the idea to “offload” the tracking. You can implement custom tracking, see Henrik’s post. But instead of making the request immediately, I first save it to the database and have a scheduled job send the data to Find at night.
You will need a table in the DB of course, and some stored procedures. See gist for the complete sql.
CREATE TABLE [dbo].[tblFindTrackingQueue] ( [Id] [bigint] IDENTITY(1,1) NOT NULL, [TrackingId] [nvarchar](max) NOT NULL, [NrOfHits] [int] NOT NULL, [Query] [nvarchar](max) NOT NULL, [Tags] [nvarchar](max) NOT NULL ); GO CREATE PROCEDURE [dbo].[FindTrackingQueue_Save] ( @TrackingId NVARCHAR(max), @NrOfHits INT, @Query NVARCHAR(max), @Tags NVARCHAR(max) ) AS BEGIN INSERT INTO [dbo].[tblFindTrackingQueue] ([TrackingId] ,[NrOfHits] ,[Query] ,[Tags]) VALUES (@TrackingId, @NrOfHits, @Query, @Tags) END GO
Next I created a “FindTrackingService” that you can use to add the data to the table, delete it, etc. See gist for the complete code.
To use FindTrackingService you will need to remove “.Track()” from your query and use the following. The input you need is a “the query”, “the amount of results for the query”, “a tracking id”, and “the tags”.
IStatisticTagsHelper statisticTagsHelper = ServiceLocator.Current.GetInstance(); IFindTrackingService findTrackingService = ServiceLocator.Current.GetInstance(); string trackId = new TrackContext().Id; IEnumerable tags = statisticTagsHelper.GetTags(false); findTrackingService.SaveTrackingInformation("yourQuery", totalMatching, trackId, tags);
To send the data to Find I created a scheduled job that does nothing more than loop through the database records and send them to Find, pausing after every 25 requests to not get the same error I was trying to fix.
The complete solution is in a gist.
P.S. Happy New Year!