i am using react js,
have search field
<input
type="search"
onChange={this.updateSearchText}/>
function updateSearch:
updateSearchText = (e) => {
this.setState({
searchText: e.target.value
}, function () {
fetch("https://api.example.com/search/?key"+ this.state.searchText)
.then((response) => {
this.props.searchResult(response.data)
})
});
};
my issue is that if type text very quickly, first letter triggers search request and it update the props after second request has sent. so i get only first letters result.
how can i restrict first request if i type second one?
You can use "throttling" and "debouncing" your input. You can refer https://css-tricks.com/debouncing-throttling-explained-examples/ to understand it.
One of the solution that worked for me was to create "queue". The purpose of the queue was if we add a task to the queue, the task goes in front of the queue and if we add a second task to the queue, the task goes in the second position. If we add a third task to the queue, the task replaces the second.
So there is a maximum of two tasks in the queue. As soon as the first task has ended, the second task is executed etc.
So you always have the same result, and you limit your api calls in function of many parameters. If the user has a slow internet connexion, the first request will take some time to execute, so there won't be a lot of requests.
Related
I'm trying to create a slash command using discord.js v13 to change the names of voice channels. I am using this code to do this :
module.exports = {
data: new SlashCommandBuilder()
.setName('name')
.setDescription('Set name for your voice channel')
.addStringOption(option => option.setName('name').setDescription('Enter your name').setRequired(true)),
async execute(interaction) {
const name = interaction.options.getString('name');
if (!interaction.member.voice.channel) await interaction.reply('Error not in a voice channel!');
else {
await interaction.member.voice.channel.setName(name);
await interaction.reply('Done!');
}
},
};
This code is fine and makes the job done. But as you know I can change the voice channel's name only 2 times per 10 minutes because of the limit rate. So if a user tries to change the voice channel's name for the third time, I won't get any error on the console, and discord js will queue this request for later and will do it after 10 minutes. But the user gets this error on discord: This interaction failed.
I want to check if there was a rate limit for my request, and if is, don't send the request and just reply to the user. Is this possible?
There is no inherent functionality that is able to handle the situation in the way you want it to, but the problem is soluble using regular old JavaScript. For example, you could use an integer to indicate how many times the command has been used and use setTimeout() to decrement it 10 minutes after the command was called. That way you can check if the int is equal to 2 in which case you skip the .setName().
There are undoubtedly other ways to implement the same or similar behavior, but, to answer your question, unfortunately the discordjs/voice library does not provide any simple way to do it.
I would like to ping a user in a channel (to alert them to it) then delete the message.
I have seen this on many large discord servers, they use custom bots for it so I think it wouldn't be too hard!
Inside your guildMemberAdd event get, the channel you want to send the ping in, then do channel.send(`${member.user}`).
Here, member is the argument you gave to the callback function in the event. member.user will ping them in that channel.
send() method returns the message you sent as a promise, which means you can just catch that message and delete it like this: send().then(message => message.delete()).
You can provide timeout as an optional parameter to the delete() method if you want to delete the message after a specific period of time and not instantly. This is what the whole code will look like:
bot.on('guildMemberAdd', (member) => {
const channel = member.guild.channels.cache.get('id'); // get the channel using the id
channel.send(`${member.user}`)
.then(message => message.delete());
}
We are using React 16.1.1 version along with Redux.
If already one react forms Add user process is going on , which is taking a bit longer time, application not allowing to add another user again ( if earlier process is not completed ). Save button not getting hit again.
Is it possible to have concerent ( add user events ) multiple user addition one after another even though its taking longer duration
Sample Code below
If AddUser request is taking long time, then application wont allow to add another new user immidiately if we do so.
/* Saga File ************************************/
export function* watchAddUser() {
while (true) {
const action = yield take(CREATE_USER_REQUEST)
try {
const response = yield call(userService.addUser, {
userData: action.payload.userdata
})
yield put(addUserSuccess(response))
// Call for User listing service
const responseForUserList = yield call(userService.index)
} catch (error) {
yield put(addUserFailure(error.data))
}
}
}
/* Saga File ************************************/
Is it possible to have one saga action is yet processing , still we are initiating same action again.
Ex:
If user "ABC" record is getting added via addUser form, this process is taking more than 2 minutes time. Backend java thread is running to complete the process.
Meanwhile we came on user listing page to add new record and and start another user record "xyz" creation, which is not working as first user record call saga process is not completed.
Is it possible to achieve it , like shown in above example assuming "CREATE_USER_REQUEST" process is not completed, so how to make is another user creation working ?
Found below link to overcome new async call request.
https://github.com/redux-saga/redux-saga/tree/master/docs/api#spawnfn-args
yield spawn(userList, action)
"creates a detached task. A detached task remains independent from its parent and acts like a top-level task. The parent will not wait for detached tasks to terminate before returning and all events which may affect the parent or the detached task are completely independents (error, cancellation)."
It is working now.
Thank you
We are using azure search and need to implement a retry stratgey as well as storing the Ids of failed documents as described.
Is there any documentation/samples on how to implement a RetryPolicy strategy in Azure Search.
Thanks
This is what I used:
private async Task<DocumentIndexResult> IndexWithExponentialBackoffAsync(IndexBatch<IndexModel> indexBatch)
{
return await Policy
.Handle<IndexBatchException>()
.WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, span) =>
{
indexBatch = ((IndexBatchException)ex).FindFailedActionsToRetry(indexBatch, x => x.Id);
})
.ExecuteAsync(async () => await _searchClient.IndexAsync(indexBatch));
}
It uses the Polly library to handle exponential backoff. In this case I use a model IndexModel that has a id field named Id.
If you like to log or store the ids of the failed attempts you can do that in the WaitAndRetryAsync function like
((IndexBatchException)ex)ex.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key).<Do something here>
There is currently no sample showing how to properly retry on IndexBatchException. However, there is a method you can use to make it easier to implement: IndexBatchException.FindFailedActionsToRetry. This method extracts the IDs of failed documents from the IndexBatchException, correlates them with the actions in a given batch, and returns a new batch containing only the failed actions that need to be retried.
Regarding the rest of the retry logic, you might find this code in the ClientRuntime library useful. You will need to tweak the parameters based on the characteristics of your load. The important thing to remember is that you should use exponential backoff before retrying to help your service recover, since otherwise your requests may be throttled.
We have a splitter process which pushes messages to different queues. There's another process which collects and aggregates these messages for further processing.
We want to have a timeout between the moment of splitting and being aggregated.
IIUC aggregation timeout starts with the first message and is it being reset after every aggregated message (it is interval based, not for the complete message).
What's the best solution to solve this?
EDIT
Here's the best I was able to come up with, although it's a bit of a hack. First, you save a timestamp as a message header and publish it to the queue with the body:
from("somewhere")
.split(body())
.process(e -> e.getIn().setHeader("aggregation_timeout",
ZonedDateTime.now().plusSeconds(COMPLETION_TIMEOUT)))
.to("aggregation-route-uri");
Then, when consuming and aggregating, you use a custom aggregation strategy that will save the aggregation_timeout from the first message in the current group and then use a completionPredicate that reads that value to check whether the timeout has expired (alternatively, if you're aggregating in a way that keeps the message ordering intact, you could just read the header from the first message). Use a short completionTimeout as a safeguard for cases when the interval between two messages is long:
from("aggregation-route-uri")
.aggregate(bySomething())
.aggregationStrategy((oldExchange, newExchange) -> {
// read aggregation_timeout header from first message
// and set it as property in grouped exchange
// perform aggregation
})
.completionTimeout(1000) // intentionally low value, here as a safeguard
.completionPredicate(e -> {
// complete once the timeout has been reached
return e.getProperty("aggregation_timeout", ZonedDateTime.class)
.isAfter(ZonedDateTime.now());
})
.process(e -> // do something with aggregates);