|
1 | 1 | using Microsoft.EntityFrameworkCore; |
| 2 | +using Microsoft.Extensions.Caching.Memory; |
| 3 | +using Microsoft.Extensions.Logging; |
2 | 4 | using PocketDDD.Server.DB; |
3 | | -using PocketDDD.Server.Model.DTOs; |
4 | | -using System; |
5 | | -using System.Collections.Generic; |
6 | | -using System.Linq; |
7 | | -using System.Text; |
8 | | -using System.Threading.Tasks; |
9 | 5 | using PocketDDD.Shared.API.RequestDTOs; |
10 | 6 | using PocketDDD.Shared.API.ResponseDTOs; |
11 | 7 |
|
12 | 8 | namespace PocketDDD.Server.Services; |
13 | | -public class EventDataService |
| 9 | + |
| 10 | +public class EventDataService(PocketDDDContext dbContext, IMemoryCache memoryCache, ILogger<EventDataService> logger) |
14 | 11 | { |
15 | | - private readonly PocketDDDContext dbContext; |
| 12 | + private const string FetchLatestEventDataCacheKey = nameof(FetchLatestEventData); |
| 13 | + private const string FetchCurrentEventDetailIdCacheKey = nameof(FetchCurrentEventDetailId); |
16 | 14 |
|
17 | | - public EventDataService(PocketDDDContext dbContext) |
| 15 | + public async Task<int> FetchCurrentEventDetailId() |
18 | 16 | { |
19 | | - this.dbContext = dbContext; |
| 17 | + if (memoryCache.TryGetValue<int?>(FetchCurrentEventDetailIdCacheKey, out var cachedEventDetailId)) |
| 18 | + return cachedEventDetailId!.Value; |
| 19 | + |
| 20 | + cachedEventDetailId = await dbContext.EventDetail.MaxAsync(e => e.Id); |
| 21 | + memoryCache.Set(FetchCurrentEventDetailIdCacheKey, cachedEventDetailId, TimeSpan.FromMinutes(5)); |
| 22 | + |
| 23 | + return cachedEventDetailId.Value; |
20 | 24 | } |
21 | 25 |
|
22 | | - public async Task<EventDataResponseDTO?> FetchLatestEventData(EventDataUpdateRequestDTO requestDTO) |
| 26 | + public async Task<EventDataResponseDTO?> FetchLatestEventData(EventDataUpdateRequestDTO requestDto) |
23 | 27 | { |
24 | | - var eventDetails = await dbContext.EventDetail |
25 | | - .Include(x => x.TimeSlots) |
26 | | - .Include(x => x.Tracks) |
27 | | - .Include(x => x.Sessions) |
28 | | - .SingleAsync(x => x.Id == 1); |
29 | | - |
30 | | - if (requestDTO.Version == eventDetails!.Version) |
| 28 | + var currentEventDetailId = await FetchCurrentEventDetailId(); |
| 29 | + |
| 30 | + if (memoryCache.TryGetValue<EventDataResponseDTO?>(FetchLatestEventDataCacheKey, out var latestEventData)) |
| 31 | + { |
| 32 | + logger.LogDebug("Retrieved latest event data from the cache {eventData}", latestEventData); |
| 33 | + } |
| 34 | + else |
| 35 | + { |
| 36 | + logger.LogDebug("No event data in the cache, retrieving from the db"); |
| 37 | + latestEventData = await dbContext.EventDetail |
| 38 | + .AsNoTracking() |
| 39 | + .AsSingleQuery() |
| 40 | + .Select(eventDetails => new EventDataResponseDTO |
| 41 | + { |
| 42 | + Id = eventDetails.Id, |
| 43 | + Version = eventDetails.Version, |
| 44 | + TimeSlots = eventDetails.TimeSlots.Select(ts => new TimeSlotDTO |
| 45 | + { |
| 46 | + Id = ts.Id, |
| 47 | + Info = ts.Info, |
| 48 | + From = ts.From, |
| 49 | + To = ts.To |
| 50 | + }).ToList(), |
| 51 | + Tracks = eventDetails.Tracks.Select(t => new TrackDTO |
| 52 | + { |
| 53 | + Id = t.Id, |
| 54 | + Name = t.Name, |
| 55 | + RoomName = t.RoomName |
| 56 | + }).ToList(), |
| 57 | + Sessions = eventDetails.Sessions.Select(s => new SessionDTO |
| 58 | + { |
| 59 | + Id = s.Id, |
| 60 | + Title = s.Title, |
| 61 | + ShortDescription = s.ShortDescription, |
| 62 | + FullDescription = s.FullDescription, |
| 63 | + Speaker = s.Speaker, |
| 64 | + TimeSlotId = s.TimeSlot.Id, |
| 65 | + TrackId = s.Track.Id |
| 66 | + }).ToList() |
| 67 | + }) |
| 68 | + .SingleAsync(e => e.Id == currentEventDetailId); |
| 69 | + |
| 70 | + memoryCache.Set(FetchLatestEventDataCacheKey, latestEventData, TimeSpan.FromMinutes(5)); |
| 71 | + logger.LogDebug("Updated the latest event data in the cache {eventData}", latestEventData); |
| 72 | + } |
| 73 | + |
| 74 | + if (requestDto.Version >= latestEventData!.Version) |
31 | 75 | return null; |
32 | 76 |
|
33 | | - var dtoResponse = new EventDataResponseDTO |
34 | | - { |
35 | | - Version = eventDetails.Version, |
36 | | - TimeSlots = eventDetails.TimeSlots.Select(ts => new TimeSlotDTO |
37 | | - { |
38 | | - Id = ts.Id, |
39 | | - Info = ts.Info, |
40 | | - From = ts.From, |
41 | | - To = ts.To |
42 | | - }).ToList(), |
43 | | - Tracks = eventDetails.Tracks.Select(t => new TrackDTO |
44 | | - { |
45 | | - Id = t.Id, |
46 | | - Name = t.Name, |
47 | | - RoomName = t.RoomName |
48 | | - }).ToList(), |
49 | | - Sessions = eventDetails.Sessions.Select(s => new SessionDTO |
50 | | - { |
51 | | - Id = s.Id, |
52 | | - Title = s.Title, |
53 | | - ShortDescription = s.ShortDescription, |
54 | | - FullDescription = s.FullDescription, |
55 | | - Speaker = s.Speaker, |
56 | | - TimeSlotId = s.TimeSlot.Id, |
57 | | - TrackId = s.Track.Id |
58 | | - }).ToList() |
59 | | - }; |
60 | | - |
61 | | - return dtoResponse; |
| 77 | + return latestEventData; |
62 | 78 | } |
63 | 79 | } |
0 commit comments