Skip to content

Commit

Permalink
Merge pull request DevChatter#71 from DevChatter/benrick/cache-Channe…
Browse files Browse the repository at this point in the history
…lSearchService

Adding Caching to ChannelSearchService
  • Loading branch information
benrick authored Apr 22, 2019
2 parents 1a95c67 + 2ec9796 commit 7de7c0c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System.Collections.Generic;
using DevChatter.DevStreams.Core.Model;
using System.Threading.Tasks;
using DevChatter.DevStreams.Core.Model;

namespace DevChatter.DevStreams.Core.Services
{
public interface IChannelSearchService
{
List<Channel> Find();
Task<Channel> GetChannelSoundex(string standardizedChannelName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using DevChatter.DevStreams.Core.Services;
using DevChatter.DevStreams.Core.Settings;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
Expand All @@ -20,29 +19,6 @@ public ChannelSearchService(IOptions<DatabaseSettings> databaseSettings)
_dbSettings = databaseSettings.Value;
}

public List<Channel> Find()
{
string sql = "SELECT * FROM [ChannelTags] WHERE ChannelId IN @ids";
using (IDbConnection connection = new SqlConnection(_dbSettings.DefaultConnection))
{
// TODO: Pull all data in 1 request and/or cache a lot.
var channels = connection.GetList<Channel>().ToList();
var tags = connection.GetList<Tag>().ToList(); // TODO: Cache this.

List<int> channelIds = channels.Select(c => c.Id).ToList();
var channelTags = connection.Query<ChannelTag>(sql,
new { ids = channelIds }).ToList();

foreach (var channel in channels)
{
var tagIdsForChannel = channelTags.Where(ct => ct.ChannelId == channel.Id).Select(ct => ct.TagId);
channel.Tags = tags.Where(tag => tagIdsForChannel.Contains(tag.Id)).ToList();
}

return channels;
}
}

public async Task<Channel> GetChannelSoundex(string standardizedChannelName)
{
var sql = @"SELECT TOP 1 * FROM Channels WHERE SOUNDEX(Name) = SOUNDEX(@standardizedChannelName)
Expand Down
8 changes: 4 additions & 4 deletions src/DevChatter.DevStreams.Infra.GraphQL/DevStreamsQuery.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System.Collections.Generic;
using DevChatter.DevStreams.Core.Data;
using DevChatter.DevStreams.Core.Data;
using DevChatter.DevStreams.Core.Model;
using DevChatter.DevStreams.Core.Services;
using DevChatter.DevStreams.Core.Twitch;
using DevChatter.DevStreams.Infra.GraphQL.Types;
using GraphQL.Types;
using System.Collections.Generic;
using System.Linq;
using DevChatter.DevStreams.Core.Services;
using System.Threading.Tasks;
using DevChatter.DevStreams.Core.Twitch;

namespace DevChatter.DevStreams.Infra.GraphQL
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using DevChatter.DevStreams.Core.Model;
using DevChatter.DevStreams.Core.Services;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Threading.Tasks;

namespace DevChatter.DevStreams.Web.Caching
{
public class CachedChannelSearchService : IChannelSearchService
{
private readonly IChannelSearchService _searchService;
private readonly IMemoryCache _cacheLayer;

public CachedChannelSearchService(IChannelSearchService searchService, IMemoryCache cacheLayer)
{
_searchService = searchService;
_cacheLayer = cacheLayer;
}

public async Task<Channel> GetChannelSoundex(string standardizedChannelName)
{
string cacheKey = $"{nameof(IChannelSearchService)}-{nameof(GetChannelSoundex)}-{standardizedChannelName}";

var channel = await _cacheLayer.GetOrCreateAsync(cacheKey, CacheFallback);

return channel;

Task<Channel> CacheFallback(ICacheEntry entry)
{
entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(15)); // TODO: Store in Config Setting
return _searchService.GetChannelSoundex(standardizedChannelName);
}
}
}
}
11 changes: 7 additions & 4 deletions src/DevChatter.DevStreams.Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using DevChatter.DevStreams.Core.Data;
using DevChatter.DevStreams.Core.Services;
using DevChatter.DevStreams.Core.Settings;
using DevChatter.DevStreams.Core.Twitch;
using DevChatter.DevStreams.Infra.Dapper;
using DevChatter.DevStreams.Infra.Dapper.Services;
using DevChatter.DevStreams.Infra.Dapper.TypeHandlers;
using DevChatter.DevStreams.Infra.Db.Migrations;
using DevChatter.DevStreams.Infra.GraphQL;
using DevChatter.DevStreams.Infra.Twitch;
using DevChatter.DevStreams.Web.Caching;
using DevChatter.DevStreams.Web.Data;
using FluentMigrator.Runner;
using GraphQL.Server;
Expand All @@ -18,15 +20,13 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NodaTime;
using System;
using System.Linq;
using System.Threading.Tasks;
using DevChatter.DevStreams.Core.Twitch;
using DevChatter.DevStreams.Web.Caching;
using Microsoft.Extensions.Caching.Memory;

namespace DevChatter.DevStreams.Web
{
Expand Down Expand Up @@ -100,7 +100,6 @@ public void ConfigureServices(IServiceCollection services)
services.AddTransient<ITagSearchService, TagSearchService>();
services.AddTransient<ICrudRepository, DapperCrudRepository>();
services.AddScoped<IChannelRepository, DapperChannelRepository>();
services.AddTransient<IChannelSearchService, ChannelSearchService>();
services.AddTransient<IChannelAggregateService, ChannelAggregateService>();

services.AddMemoryCache();
Expand All @@ -109,6 +108,10 @@ public void ConfigureServices(IServiceCollection services)
CachedTwitchStreamService TwitchServiceFactory(IServiceProvider x) => new CachedTwitchStreamService((ITwitchStreamService) x.GetService(typeof(TwitchStreamService)), (IMemoryCache)x.GetService(typeof(IMemoryCache)));
services.AddScoped<ITwitchStreamService, CachedTwitchStreamService>(TwitchServiceFactory);

services.AddScoped<ChannelSearchService>();
CachedChannelSearchService ChannelSearchServiceFactory(IServiceProvider x) => new CachedChannelSearchService((IChannelSearchService) x.GetService(typeof(ChannelSearchService)), (IMemoryCache)x.GetService(typeof(IMemoryCache)));
services.AddScoped<IChannelSearchService, CachedChannelSearchService>(ChannelSearchServiceFactory);

services.AddScoped<ITwitchChannelService, TwitchChannelService>();

services.AddSingleton<IClock>(SystemClock.Instance);
Expand Down

0 comments on commit 7de7c0c

Please sign in to comment.