Управление уровнями согласованности сеанса CosmosDb с помощью токена сеанса в веб-среде - PullRequest
0 голосов
/ 24 мая 2018

В моей среде ASP.NET Core 2.x обращается к CosmosDb (он же DocumentDb) с помощью .NET SDK.

Уровень согласованности по умолчанию для моей коллекции установлен на "Сеанс".Для моего варианта использования мне нужен один аутентифицированный веб-пользователь, чтобы всегда иметь согласованные данные в терминах чтения / записи между веб-запросами.

У меня есть некоторая логика репозитория CosmosDB, которая сделана доступной для логики моего контроллера через ASP.Внедрение зависимости NET Core Singleton как таковое:

services.AddSingleton<DocumentDBRepository, DocumentDBRepository>(x =>
                 new DocumentDBRepository(
                     WebUtil.GetMachineConfig("DOCDB_ENDPOINT", Configuration),
                     WebUtil.GetMachineConfig("DOCDB_KEY", Configuration),
                     WebUtil.GetMachineConfig("DOCDB_DB", Configuration),
                     "MyCollection",
                     maxDocDbCons));

DocumentDBRespository создает клиента космоса следующим образом:

  public DocumentDBRepository(string endpoint, string authkey, string database, string collection, int maxConnections)
        {
            _Collection = collection;
            _DatabaseId = database;
            _Client = new DocumentClient(new Uri(endpoint), authkey,
                new ConnectionPolicy()
                {
                    MaxConnectionLimit = maxConnections,
                    ConnectionMode = ConnectionMode.Direct,
                    ConnectionProtocol = Protocol.Tcp,
                    RetryOptions = new RetryOptions()
                    {
                        MaxRetryAttemptsOnThrottledRequests = 10
                    }
                });

            _Client.OpenAsync().Wait();
            CreateDatabaseIfNotExistsAsync().Wait();
            CreateCollectionIfNotExistsAsync().Wait();
        }

Насколько я понимаю, это означает, что один клиент CosmosDB на сервер веб-приложений.У меня есть несколько серверов веб-приложений, поэтому один пользователь может подключиться к CosmosDB с нескольких серверов приложений и разных клиентов CosmosDb.

Перед тем, как пользователь взаимодействует с ComosDb, я проверяю его объект сеанса на наличие CosmosDb SessionToken, например, так::

string docDbSessionToken = HttpContext.Session.GetString("StorageSessionToken");

Затем, например, при написании документа метод выглядит примерно так:

 public async Task<Document> CreateItemAsync<T>(T item, Ref<string> sessionTokenOut, string sessionTokenIn = null)
        {
            ResourceResponse<Document> response = null;
            if (string.IsNullOrEmpty(sessionTokenIn))
            {
                response = await _Client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_DatabaseId, _Collection), item);
            }
            else
            {
                response = await _Client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_DatabaseId, _Collection), item, new RequestOptions() { SessionToken = sessionTokenIn });
            }

            sessionTokenOut.Value = response.SessionToken;
            Document created = response.Resource;
            return created;
        }

Идея состоит в том, что если у нас есть токен сеанса, мы передаем его ви использовать это.Если у нас его нет, просто создайте документ и затем верните вновь созданный токен сеанса обратно вызывающей стороне.Это прекрасно работает ...

Кроме того, мне неясно, почему, когда я передаю токен сеанса, я получаю РАЗНЫЙ токен назад.Другими словами, когда возвращается _Client.CreateDocumentAsync, response.SessionToken всегда отличается от параметра sessionTokenIn.

Означает ли это, что я должен использовать новый токен сеанса с этого момента для этого пользователя?Означает ли это, что я должен игнорировать новый токен сеанса и использовать начальный токен сеанса?

Как долго длится один из этих "сеансов"?Являются ли они сеансами в традиционном смысле?

В конечном счете, мне просто нужно убедиться, что один и тот же пользователь всегда может читать свои записи, независимо от того, с каким AppServer они соединяются или сколько других пользователей в настоящее время используют БД.

Заранее спасибо!

1 Ответ

0 голосов
/ 24 мая 2018

Я думаю, что путаница здесь в том, что такое сессия?

В большинстве сценариев / сред рассматривается сессия как статический идентификатор (корреляция), где, как и в случае с космосом, sessionToken является динамическим (вид закладки / представления состояния базы данных космоса, , который изменяется при записи ),Присвоение ему имени 'sessionToken' может быть корнем этой путаницы.

В этом конкретном сценарии вы должны использовать " возвращенный сессионный токен " из API-интерфейса космоса.

...