I have developed a bot and it is in use. Sometimes bot is taking more time to respond for queries.
At that time users are posting 3 to 4 questions consecutively.
Is there any option for if user posts next question before the answer was responded, we have to give message like “Please wait, am still looking for the answer.”
I am using Azure bot and Directline channel.
Getting multiple messages in quick succession can be a problem, and it can be hard to know how your bot should deal with it. Suppose you have a waterfall dialog that displays a confirm prompt like "Are you satisfied with this?" on step 1, and the user says "yes" twice in two different messages that your bot then processes simultaneously. What will happen? Well there are two possibilities:
- If both threads load the bot state before either of them save the bot state, then they will both process the turn the same way and process step 2 twice. This means whatever prompt is on step 2 like "Okay, do you need anything else?" will get displayed twice. The bot state will be the same in both threads, so after they both save the bot state the bot will still be on step 2. This isn't so bad, because the user can just respond to the prompt intuitively and continue on to step 3.
- If the first thread processes step 2 so quickly that it saves the bot state before the second thread loads the bot state, then the second thread will treat the user's second "yes" as a reply to step 2 instead of step 1. So if step 2 has another confirm prompt like "Okay, do you need anything else?" then the second "yes" will be treated as an answer to step 2's confirm prompt instead of step 1's confirm prompt, and the bot will then display step 3. This could be bad if the user didn't want to say yes to the second prompt, but that problem can be mitigated by good navigation options. Alternatively, if step 2 has some other kind of prompt like a choice prompt and it doesn't recognize "yes" as an option, the second thread will just display the retry prompt and the bot will remain on step 2. Again, this isn't so bad because the user will then have a chance to respond to the prompt correctly.
As seen in the comments, there are many avenues to explore when it comes to addressing this problem. I will say right now that the recommended solution is to leave the problem alone and just let the bot run its course. This is because it's usually not a big enough problem to worry about, and the user will quickly understand that they need to slow down and enter messages one at a time. If you must address the problem, you've already seen several possible solutions mentioned in the comments, and these include both client-side solutions and bot-side solutions. I will now focus on the bot-side solutions since you said that's all you're looking for.
Option 1: Send a typing indicator
Many channels have an indicator that lets users know that someone is typing. Bot Framework bots can simulate this using the "typing" activity type. There is a middleware that handles this for you, and it's built into the Bot Builder SDK. You can look at its source code to see how to send a typing activity manually.
Option 2: Send a preemptive message
If you know the bot is going to take a while to process the user's message, you can go ahead and send a message back to the user before the bot does its lengthy processing. This will let the user know that they shouldn't send any more messages to the bot until they get a real response. This serves the same purpose as option 1 and it can be used in conjunction with it to give it some extra oomph.
Option 3: Keep track of simultaneous threads with bot state
This option is not recommended, but it is what you originally asked for. In order for the bot to know that it's currently processing a message from the user in a different thread, the first thread will need to have saved something in bot state that indicates to the second thread that the bot is processing a message. This is messy and complicated and prone to failures, and you will need to worry about all the usual multithreading concerns like race conditions and deadlocks. It would have to go something like this:
- When the bot starts processing a message, it reads a special property from its bot state (i.e. conversation state or user state or whatever). This property could act as a semaphore that counts up from 0 to 1 when the bot writes to it, or it could act as a normal lock that's just true or false depending on whether the bot is processing a message in that conversation. This could potentially happen in some custom middleware or even a custom adapter.
- If the bot reads the property and it indicates that no other threads are processing any messages in that conversation at the moment, the bot needs to immediately change that property and write it to storage. This is where race conditions might come into play, because two threads could try to read the value before either of them write to it and then they'd both think they should proceed. You'd have to test your state storage to make sure it can adequately lock each conversation's entry to prevent this from happening.
- The bot will then proceed to process the turn as usual.
- The bot has to make sure it changes the special property back to the way it was before when it's done processing, so it will be able to process messages again on the next turn. This is really important so you should also make this happen in your adapter's error handler. Even then, there's a possibility that the property won't get changed back, and that will break your bot. You might want to come up with some way of getting it to change back automatically after some timeout period.
- If the bot reads the property and it indicates that another thread is processing a message, then it will send your “Please wait, am still looking for the answer.” message to the user and end the turn.
See also this troubleshooting doc