Skip to content

Commit 8679a39

Browse files
Back out of fixing async methods, they don't mix well with views in .NET framework
Revert: "Workaround for no native async in views in .NET frameworkRevert "Need a caching mechanism that supports async" This reverts commit 69d007b. Revert "Don't mix synchronous code with asynchronous code" This reverts commit 2742a16.
1 parent f36517f commit 8679a39

File tree

3 files changed

+45
-99
lines changed

3 files changed

+45
-99
lines changed

OurUmbraco/Forum/Controllers/LatestActivityController.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
using System.Linq;
2-
using System.Threading.Tasks;
32
using System.Web.Mvc;
3+
using OurUmbraco.Community.People;
44
using OurUmbraco.Forum.Services;
55
using Umbraco.Web.Mvc;
66

77
namespace OurUmbraco.Forum.Controllers
88
{
99
public class LatestActivityController : SurfaceController
1010
{
11-
public async Task<ActionResult> LatestActivity(int numberOfTopics = 10)
11+
public ActionResult LatestActivity(int numberOfTopics = 10)
1212
{
1313
var discourseService = new DiscourseService();
14-
var discourseQuestions = await discourseService.GetLatestTopicsAsync("questions", 5);
15-
var discourseTopics = discourseQuestions.Take(numberOfTopics).ToList();
14+
var discourseTopics = discourseService.GetLatestTopics("questions", 5).Take(numberOfTopics).ToList();
1615

1716
return PartialView("~/Views/Partials/Home/LatestForumActivity.cshtml", discourseTopics);
1817
}

OurUmbraco/Forum/Services/DiscourseService.cs

Lines changed: 40 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@
22
using OurUmbraco.Forum.Extensions;
33
using OurUmbraco.Forum.Models;
44
using System;
5-
using System.Collections.Concurrent;
65
using System.Collections.Generic;
76
using System.Linq;
87
using System.Net.Http;
9-
using System.Runtime.Caching;
10-
using System.Threading;
11-
using System.Threading.Tasks;
128

139
namespace OurUmbraco.Forum.Services
1410
{
1511
internal class DiscourseService
1612
{
17-
internal async Task<DiscourseTopic> GetTopicByOldIdAsync(int id)
13+
internal DiscourseTopic GetTopicByOldIdAsync(int id)
1814
{
1915
var handler = new HttpClientHandler
2016
{
@@ -31,119 +27,71 @@ internal async Task<DiscourseTopic> GetTopicByOldIdAsync(int id)
3127
client.DefaultRequestHeaders.Add("Api-Key", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiKey"]}");
3228
client.DefaultRequestHeaders.Add("Api-Username", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiUsername"]}");
3329

34-
var result = await client.GetAsync($"t/external_id/{id}.json");
30+
var result = client.GetAsync($"t/external_id/{id}.json").Result;
3531

3632
if (result.IsSuccessStatusCode == false)
3733
{
3834
return null;
3935
}
4036
else
4137
{
42-
var resultContent = await result.Content.ReadAsStringAsync();
38+
var resultContent = result.Content.ReadAsStringAsync().Result;
4339
var discourseTopic = JsonConvert.DeserializeObject<DiscourseTopic>(resultContent);
4440
return discourseTopic;
4541
}
4642
}
4743
}
4844

49-
internal async Task<List<DiscourseTopic>> GetLatestTopicsAsync(string categorySlug, int categoryId)
45+
internal List<DiscourseTopic> GetLatestTopics(string categorySlug, int categoryId)
5046
{
51-
var cacheKey = "LatestDiscourseTopics" + categorySlug + categoryId;
5247

53-
return await AsyncMemoryCache.GetOrAddAsync("myCacheKey", async () =>
54-
{
55-
var forumBaseUrl = System.Configuration.ConfigurationManager.AppSettings["DiscourseApiBaseUrl"];
48+
var cacheKey = "LatestDiscourseTopics" + categorySlug + categoryId;
5649

57-
using (var client = new HttpClient())
50+
return (List<DiscourseTopic>)Umbraco.Core.ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(
51+
cacheKey,
52+
() =>
5853
{
59-
client.BaseAddress = new Uri(forumBaseUrl);
60-
client.DefaultRequestHeaders.Add("Api-Key", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiKey"]}");
61-
client.DefaultRequestHeaders.Add("Api-Username", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiUsername"]}");
54+
var forumBaseUrl = System.Configuration.ConfigurationManager.AppSettings["DiscourseApiBaseUrl"];
6255

63-
var endPoint = $"c/{categorySlug}/{categoryId}.json?order=created";
64-
var result = await client.GetAsync(endPoint);
65-
if (!result.IsSuccessStatusCode)
56+
using (var client = new HttpClient())
6657
{
67-
var resultContent = await result.Content.ReadAsStringAsync();
68-
var errorModel = JsonConvert.DeserializeObject<ErrorModel>(resultContent);
69-
string errors = string.Join(", ", errorModel.Errors);
58+
client.BaseAddress = new Uri(forumBaseUrl);
59+
client.DefaultRequestHeaders.Add("Api-Key", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiKey"]}");
60+
client.DefaultRequestHeaders.Add("Api-Username", $"{System.Configuration.ConfigurationManager.AppSettings["DiscourseApiUsername"]}");
7061

71-
// Logger.Debug(typeof(DiscourseController), $"Listing latest topics from {endPoint} didn't succeed: {errors}");
62+
var endPoint = $"c/{categorySlug}/{categoryId}.json?order=created";
63+
var result = client.GetAsync(endPoint).Result;
64+
if (result.IsSuccessStatusCode == false)
65+
{
66+
var resultContent = result.Content.ReadAsStringAsync().Result;
67+
var errorModel = JsonConvert.DeserializeObject<ErrorModel>(resultContent);
68+
string errors = string.Join(", ", errorModel.Errors);
7269

73-
return null;
74-
}
75-
else
76-
{
77-
var resultContent = await result.Content.ReadAsStringAsync();
78-
var latestTopics = JsonConvert.DeserializeObject<TopicListModel>(resultContent);
79-
foreach (var topic in latestTopics.TopicList.Topics)
70+
//Logger.Debug(typeof(DiscourseController), $"Listing lastest topic from {endPoint} didn't succeeed: {errors}");
71+
72+
return null;
73+
}
74+
else
8075
{
81-
var latestPostUser = topic.LastPosterUsername;
82-
var user = latestTopics.Users.FirstOrDefault(x => x.Username == latestPostUser);
83-
if (user != null)
76+
var resultContent = result.Content.ReadAsStringAsync().Result;
77+
var lastestTopics = JsonConvert.DeserializeObject<TopicListModel>(resultContent);
78+
foreach (var topic in lastestTopics.TopicList.Topics)
8479
{
85-
topic.AuthorName = user.Name;
86-
topic.AuthorAvatar = $"{forumBaseUrl}{user.AvatarTemplate.Replace("{size}", "112")}";
80+
var latestPostUser = topic.LastPosterUsername;
81+
var user = lastestTopics.Users.FirstOrDefault(x => x.Username == latestPostUser);
82+
if (user != null)
83+
{
84+
topic.AuthorName = user.Name;
85+
topic.AuthorAvatar = $"{forumBaseUrl}{user.AvatarTemplate.Replace("{size}", "112")}";
86+
}
87+
topic.LastUpdatedFriendly = topic.LastPostedAt.ConvertToRelativeTime();
88+
topic.ForumCategory = "Umbraco questions";
8789
}
88-
topic.LastUpdatedFriendly = topic.LastPostedAt.ConvertToRelativeTime();
89-
topic.ForumCategory = "Umbraco questions";
90-
}
9190

92-
return latestTopics.TopicList.Topics.OrderByDescending(x => x.LastPostedAt).ToList();
91+
return lastestTopics.TopicList.Topics.OrderByDescending(x => x.LastPostedAt).ToList();
92+
}
9393
}
94-
}
95-
}, TimeSpan.FromMinutes(5));
94+
}, TimeSpan.FromMinutes(5));
9695
}
9796
}
9897
}
99-
100-
101-
public static class AsyncMemoryCache
102-
{
103-
private static readonly MemoryCache _cache = MemoryCache.Default;
104-
private static readonly ConcurrentDictionary<string, SemaphoreSlim> _locks = new ConcurrentDictionary<string, SemaphoreSlim>();
105-
106-
public static async Task<T> GetOrAddAsync<T>(string key, Func<Task<T>> valueFactory, TimeSpan absoluteExpiration)
107-
{
108-
if (_cache.Contains(key))
109-
{
110-
return (T)_cache.Get(key);
111-
}
112-
113-
var semaphore = _locks.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
114-
115-
try
116-
{
117-
await semaphore.WaitAsync();
118-
119-
// Double-check if the value was added while waiting for the lock
120-
if (_cache.Contains(key))
121-
{
122-
return (T)_cache.Get(key);
123-
}
124-
125-
T result;
126-
try
127-
{
128-
result = await valueFactory();
129-
}
130-
catch (Exception ex)
131-
{
132-
// Log the exception (optional)
133-
throw; // Re-throw or handle as needed
134-
}
135-
136-
if (result != null)
137-
{
138-
_cache.Add(key, result, DateTimeOffset.Now.Add(absoluteExpiration));
139-
}
140-
141-
return result;
142-
}
143-
finally
144-
{
145-
semaphore.Release();
146-
_locks.TryRemove(key, out _); // Clean up the lock
147-
}
148-
}
149-
}

OurUmbraco/Forum/Services/TopicService.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Threading.Tasks;
54
using System.Web;
65
using OurUmbraco.Forum.Extensions;
76
using OurUmbraco.Forum.Models;
@@ -420,7 +419,7 @@ public void Delete(Topic topic)
420419
/// <remarks>
421420
/// So that we don't have to look this up multiple times in a single request, this will use the given ICacheProvider to cache it
422421
/// </remarks>
423-
public async Task<ReadOnlyTopic> CurrentTopicAsync(HttpContextBase context, ICacheProvider cache, MemberData memberData, IPublishedContent content)
422+
public ReadOnlyTopic CurrentTopic(HttpContextBase context, ICacheProvider cache, MemberData memberData, IPublishedContent content)
424423
{
425424
var topic = (ReadOnlyTopic)cache.GetCacheItem(typeof(TopicService) + "-CurrentTopic", () =>
426425
{
@@ -506,7 +505,7 @@ public async Task<ReadOnlyTopic> CurrentTopicAsync(HttpContextBase context, ICac
506505

507506
// Check if related topic exists on new forum
508507
var discourseService = new DiscourseService();
509-
var discourseTopic = await discourseService.GetTopicByOldIdAsync(topic.Id);
508+
var discourseTopic = discourseService.GetTopicByOldIdAsync(topic.Id);
510509
topic.DiscourseTopic = discourseTopic;
511510

512511
return topic;

0 commit comments

Comments
 (0)