.Net-сеанс (режим StateServer) не синхронизируется, если манипулировать им после завершения запроса

Меня немного расстраивает эта проблема:

У меня есть веб-сайт, который управляет некоторыми файлами для загрузки, потому что эти файлы очень большие и должны быть организованы в папки, а затем уплотнены, я создаю структуру Ajax, которая выполняет эту работу в фоновом режиме, и когда эти файлы будут готовы к загрузке , это задание изменяет статус объекта в пользовательском сеансе (bool isReady = true, просто вот так).

Чтобы достичь этого, когда пользователь нажимает кнопку «загрузить», сообщение jquery отправляется в API, и этот API запускает задание «организатор» и завершает код (основной поток, область действия запроса), оставляя фоновый поток, выполняющий магия (это так красиво, ха-ха).

Это «организаторское» задание является фоновым потоком, который получает HttpSessionState (HttpContext.Current.Session) параметром. Он упорядочивает и архивирует файлы, создает ссылку для загрузки и, в конце концов, изменяет объект в сеансе с помощью HttpSessionState, полученного параметром param.

Это отлично работает, когда я использую сеансовый режим «InProc» (я был очень рад развернуть этот мир искусства в продакшене после тестов).

Но мои кошмары начались, когда я развернул проект в производственной среде, потому что мы используем режим «StateServer» в этой среде. В этих условиях изменения не применяются.

До сих пор я замечал, что в StateServer каждое изменение, которое я делаю в фоновом потоке, не «фиксируется» для сеанса, когда изменения происходят ПОСЛЕ завершения пользовательского запроса (поток, запускающий поток). Если я напишу thread.join (), чтобы дождаться завершения потока, применяются изменения, сделанные внутри потока.

Я думаю об использовании БД для хранения этих значений, но я потеряю некоторую производительность :(

[HttpPost]
        [Route("startDownloadNow")]
        public void StartDownloadNow(DownloadStatusProxy input)
        {
            //some pieces of code...
            ... 

            //add the download request in the user session
            Downloads.Add(data);

            //pass the session as parameter to the thread
            //cause the thread itself don't know the current httpcontext session
            HttpSessionState session = HttpContext.Current.Session;
            Thread thread = new Thread(() => ProccessDownload(data, session));
            thread.Start();
            //here, if I put a thread.join(), the changes inside the thread are applied correctly, but I can't do this, otherwise, it ceases to be ajax
        }

private void ProccessDownload(DownloadStatus currentDownload, HttpSessionState session)
        {
            List<DownloadStatus> listDownload = ((List<DownloadStatus>)session["Downloads"]);

            try
            {
                //just make the magic...
                string downloadUrl = CartClient.CartDownloadNow(currentDownload.idRegion, currentDownload.idUser, currentDownload.idLanguage, currentDownload.listCartAsset.ToArray(), currentDownload.listCartAssetThumb.ToArray());

                listDownload.Find(d => d.hashId == currentDownload.hashId).downloadUrl = downloadUrl;
                listDownload.Find(d => d.hashId == currentDownload.hashId).isReady = true;
                //in this point, if I inspect the current session, the values are applied but, in the next user request, these values are in the previous state... sad... .net bad dog...
            }
            catch (Exception e)
            {
                listDownload.Find(d => d.hashId == currentDownload.hashId).msgError = Utils.GetAllErrors(e);
                LogService.Log(e);
            }
            //this was a desesperated try, I retrieve the object, manipulated and put it back again to the session, but it doesn't works too...
            session["Downloads"] = listDownload;
        }

Если вы уже используете «StateServer», то я не понимаю, почему фраза «Я подумываю об использовании БД для хранения этих значений, но я потеряю некоторую производительность» вообще имеет смысл. Что такое StateServer, если это не база данных? Если бы это был я, я бы отказался от любой концепции состояния сеанса на веб-сервере. Это сломанная концепция, которая не масштабируется. Храните все в базе данных (без адаптера для сохранения состояния сеанса).

spender 06.06.2018 13:24

Я думаю, что StateServer быстрее, чем хранить данные в БД, потому что сеанс работает в памяти, а БД использует ввод-вывод. Я ошибся? Или этот спектакль не такой большой, что я должен его учитывать?

William Borgo 06.06.2018 13:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
22
0

Другие вопросы по теме