TL;DR
lorsque vous avez beaucoup trop de travail à faire sur le serveur concernant les limites d'API
confiez une partie du travail aux navigateurs de vos clients pour l'effectuer - en envoyant les résultats à votre base de données
le problème
la semaine dernière, je traitais les limites d'API (fournisseur-g) et trop nombreuses requêtes de géolocalisation provenant d'un(des) serveur(s). J'ai travaillé un peu à cela, en faisant des choses en arrière-plan, avec des réessais périodiques - vous savez : les trucs standards…
l'API en question est limitée par IP, et la documentation recommande de tirer parti de cela en effectuant la plupart des appels d'API côté client - en js.
maintenant, dans ce cas particulier, j'avais absolument besoin des résultats des appels d'API pour résider côté serveur, j'ai donc adopté cette solution de compromis (de plus d'une manière)
la solution
supposez que certains clients sont prêts à brûler leur CPU pour peupler les données qui les intéressent. En langage clair, faites en sorte que certains de vos clients exécutent des tâches à partir d'une file d'attente de travail JavaScript pour amorcer la pompe qui les intéresse.
dans mon cas, j'ai certaines interfaces sélectionnées (celles intéressées par la sortie desdites tâches) exécutant un petit iframe
<!-- déposez un exécuteur de file d'attente de tâches sur certaines pages/vues/mises en page -->
<iframe height="0" width="0" style="display:none;" src="/javascript_jobs/runner"></iframe>
<!-- l'exécuteur de tâches -->
<%= javascript_include_tag :jquery %>
<%= javascript_include_tag :jobs %>
<script>
jQuery(function(){
jobs.complete = function(job){
document.write('tâche complétée ' + job.id);
document.write('<br>');
};
setTimeout(function(){ jobs.start(); }, 1000);
});
</script>
le js requis pour interagir avec la file d'attente de tâches est court et simple
tout ce qu'il fait est d'obtenir une tâche, de l'exécuter et de l'envoyer au serveur - en respectant à la fois le taux de débit et le nombre maximum de tâches à exécuter.
if(!window.jobs){
//
window.jobs = {};
window.jobs.count = 0;
window.jobs.max = 256;
window.jobs.throttle = 1000;
window.jobs.complete = function(){};
//
jobs.get_next_job = function(){
var success = function(response){
job = response['data']['job'];
if(job){
jobs.count++;
jobs.run(job, function(job){
if(jobs.count < jobs.max){
setTimeout(jobs.get_next_job, jobs.throttle);
}
});
}
};
jQuery.ajax({
'url' : '/api/jobs/next',
'type' : 'GET',
'cache' : false,
'success' : success
});
};
//
jobs.run = function(job, callback){
var code = job['code'];
var result = undefined