У нас есть сервер, который выполняет манипуляции с изображениями на основе строки запроса и затем отображает результат. Результат также кэшируется на 90 дней. Из-за сложностей некоторые манипуляции могут занимать 6-7 секунд.
Рынок, на котором мы перечисляем некоторые из наших продуктов, недавно сократил их время ожидания при загрузке изображений до низкого значения, в результате чего большинство элементов в любом конкретном фиде впервые перестали работать из-за (их сообщения об ошибке) "Таймаута изображения". Когда мы повторно отправляем канал, таких проблем не возникает, поскольку наш сервер изображений теперь кэширует изображения.
Пожалуйста, , не предлагайте попросить рынок изменить время ожидания. Они смехотворно негибки и не сотрудничают. Также, пожалуйста, не предлагайте получить более мощный сервер изображений. На самом деле это огромная ферма, и моя команда ее не контролирует.
Это оставляет меня с одним вариантом. Мне нужно "заправить кеш" перед отправкой канала на рынок. Проблема заключается в том, что фид может содержать до 5000 элементов, каждый из которых содержит как минимум 2 изображения. Это означает, что 10000 изображений.
Я использую вызов HEAD
, поскольку нам не нужно возвращать нам изображение. Я пытался использовать WebRequest
и даже Socket
в .Net Framework, вызываемом внутри асинхронного Task
(используя Task.Run () `), но CLR будет раскручиваться только где-то около 20 задач одновременно. Поскольку, в среднем, каждое изображение занимает около 4 секунд (некоторые до 6-7 секунд, некоторые только 1 секунду), вы берете 10 000/20 = 500 * 4 секунд = 2000 секунд = 33 1/3 минуты, что не является приемлемое ожидание с нашей стороны, прежде чем мы отправим канал.
Поскольку нам на самом деле не нужен ответ от нашего сервера изображений, я попытался использовать асинхронный запрос к серверу изображений, который проходит через foreach
в рекордно короткие сроки, но, как я выяснил, использовал этот асинхронный запрос Я не гарантирую, что вызов будет даже вызван к тому времени, когда код, который раскручивает все задачи, завершается, и это не помогает.
Мы используем AWS, поэтому я рассмотрел вопрос об использовании Lambdas, но это добавило бы дополнительную сложность и затраты, но массивная параллельная способность там звучит так, как будто это поможет.
Как я могу это исправить?
Тестовый сервер
public class HomeController : Controller {
private Random random;
public HomeController() {
random = new Random(DateTime.UtcNow.Millisecond);
}
public ActionResult Index(string url) {
var wait = random.Next(1, 70);
Thread.Sleep(wait * 100);
return Content(wait + " : " + url);
}
}
Тестовый клиент
class Program {
static void Main(string[] args) {
var tasks = new List<Task>();
for (var i = 0; i < 200; i++) {
Console.WriteLine(i.ToString());
var task = SendRequest("http://test.local.com/Home/Index?url=" + i);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
private static async Task SendRequest(string url) {
try {
var myWebRequest = WebRequest.Create(url);
myWebRequest.Method = "HEAD";
var foo = await myWebRequest.GetResponseAsync();
//var foo = myWebRequest.GetResponseAsync();
//var foo = myWebRequest.GetResponse();
foo.Dispose();
}
catch { }
}
}