У меня есть несколько ботов, обращающихся к CosmosDB. Они получают идентификатор пользователя через параметр URL-адреса от клиента.
Моя проблема возникает при использовании одного и того же бота в разных экземплярах одновременно.
Допустим, я начинаю разговор с идентификатором пользователя "1", введите некоторые данные, такие как имя, возраст, пол. В середине разговора я открываю другой сайт с идентификатором пользователя «2». Пользователь 2 вводит имя. Пользователь 1 завершает создание профиля. Пользователю 2 предлагается возраст. Внезапно идентификатор пользователя от пользователя 2 изменится на «1», и данные профиля будут идентичны данным пользователя от пользователя 1.
Время от времени я получаю следующую ошибку:
{ code: 412,
body: ‘{“code”:“PreconditionFailed”,“message”:“Operation cannot be performed because one of the specified precondition is not met., \r\nRequestStartTime: 2019-03-07T20:57:19.6998897Z, RequestEndTime: 2019-03-07T20:57:19.7098745Z, Number of regions attempted: 1\r\nResponseTime: 2019-03-07T20:57:19.7098745Z, StoreResult: StorePhysicalAddress: rntbd://cdb-ms-prod-westeurope1-fd21.documents.azure.com:16817/apps/9bc5d0cc-9b7c-4b1d-9be2-0fa2654271c4/services/3507a423-5215-48ca-995a-8763ec527db8/partitions/940cd512-aa34-4c93-9596-743de41037da/replicas/131964420031154286p/, LSN: 172, GlobalCommittedLsn: 171, PartitionKeyRangeId: 0, IsValid: True, StatusCode: 412, SubStatusCode: 0, RequestCharge: 1.24, ItemLSN: -1, SessionToken: 172, UsingLocalLSN: False, TransportException: null, ResourceType: Document, OperationType: Replace\r\n, Microsoft.Azure.Documents.Common/2.2.0.0”}’,
activityId: ‘fbdaeedb-a73f-4052-bd55-b1417b10583f’ }
Итак, кажется, бот каким-то образом перепутал идентификаторы пользователей.
Я сохраняю UserState и ConversationState в локальном хранилище, поскольку они не нужны для сохранения в моей БД:
// Local browser storage
const memoryStorageLocal = new MemoryStorage();
// ConversationState and UserState
const conversationState = new ConversationState(memoryStorageLocal);
const userState = new UserState(memoryStorageLocal);
Я получаю идентификатор пользователя следующим образом, что соответствует параметру URL
for (var idx in turnContext.activity.membersAdded) {
if (turnContext.activity.membersAdded[idx].id !== turnContext.activity.recipient.id) {
console.log("User added");
this.userID = turnContext.activity.membersAdded[idx].id;
}
}
Я читаю и пишу в БД следующим образом:
// Read userData object
try {
user = await this.memoryStorage.read([this.userID]);
console.log("User Object read from DB: " + util.inspect(user, false, null, true /* enable colors */));
}
catch(e) {
console.log("Reading user data failed");
console.log(e);
}
// If user is new, create UserData object and save it to DB and read it for further use
if(isEmpty(user)) {
await step.context.sendActivity("New User Detected");
this.changes[this.userID] = this.userData;
await this.memoryStorage.write(this.changes);
user = await this.memoryStorage.read([this.userID]);
}
Это «пустой» объект userData, который я сохраняю в БД, если пользователь новый:
this.userData = {
name: "",
age: "",
gender: "",
education: "",
major: "",
riskData: {
roundCounter: "",
riskAssessmentComplete: "",
riskDescription: "",
repeat: "",
choices: "",
},
investData: {
repeat: "",
order: "",
choice: "",
follow: "",
win1: "",
win2: "",
loss1: "",
loss2: "",
},
endRepeat: "",
eTag: '*',
}
Мне кажется, что настоящая проблема не в том, как я читаю и пишу с и на CosmosDB, а в том, что нет разных экземпляров бота, поскольку идентификаторы пользователя и данные пользователя смешиваются при их одновременном использовании.
Как я могу заставить эту работу? Вы можете найти мой код бота здесь:
https://github.com/FRANZKAFKA13/roboadvisoryBot
Заранее спасибо за любую помощь!