2017-09-11 4 views
0

J'ai implémenté une méthode HTTP Spring Boot pour permettre à 5 000 abonnés d'accéder à n'importe quel compte Twitter.Twitter4j - AsyncTwitter: Associer la réponse dans le TwitterListener à la demande d'ouverture

Dans le backend, d'abord, je suis en train de récupérer le Ids 5000 suiveur avec

IDs ids = twitter.getFollowersIDs(username, -1); 

Après cela, je partagerai les 5000 ids en morceaux de 100.

Puis, je me sers AsyncTwitter à envoyer plusieurs requêtes HTTP "lookupUsers" à Twitter de façon asynchrone et mettre le thread en pause avec LOCK.wait();

Puis, avec la méthode d'écoute suivante:

@Override 
    public void lookedupUsers(ResponseList<User> users) 

je lis chaque réponse et ajouter la liste des utilisateurs retourné dans une propriété de type « followerAccounts ». En fin de compte, lorsque je récupère toutes les réponses, je débloque le thread principal avec LOCK.notify() et je renvoie le "followerAccounts" en réponse à la méthode HTTP. Le problème est que lorsque deux utilisateurs externes appellent simultanément la même méthode HTTP de printemps, il n'y a aucun moyen de vérifier dans TwitterListener quelle méthode de recherche est utilisée pour les deux requêtes HTTP auxquelles elle fait référence.

Existe-t-il un moyen d'obtenir par ex. certains en-têtes de la réponse HTTP Twitter à l'intérieur de la méthode ViewedupUsers (utilisateurs ResponseList) ou n'importe quel moyen de transmettre des paramètres qui indiquent en quelque sorte la requête "lookupUsers" liée à la réponse?

Je ne veux pas synchroniser ma méthode HTTP, car elle ne prend pas en charge un grand nombre de requêtes parallèles.

+0

Il me semble que ce que vous appelez le "thread principal" est en fait le fil commencé avec la requête HTTP ... Je ne vois pas comment il peut être mélangé avec les autres demandes ... Peut-être que je n'ai pas Je vous comprends bien. En tout cas, mettre un fil en pause ne me semble pas bien. – Fernando

Répondre

2

Malheureusement, twitter async api ne semble pas assez flexible pour répondre facilement à vos besoins. Toutes ses méthodes ne renvoient rien (void) donc il n'est pas possible de collecter des réponses (Futures) pour une requête http particulière. En fait, il fournit uniquement des écouteurs globaux pour toutes les méthodes API à la place pour des rappels plus fins pour chaque méthode. Sinon, il serait possible de fournir une instance de rappel distincte pour chaque requête http.

Il est toujours possible de séparer les réponses pour chaque requête http en utilisant seulement l'écouteur global, mais cela nécessite beaucoup d'état thread-safe partagé avec une logique assez complexe et je ne pense pas que ce soit efficace. Au lieu de cela je suggère de ne pas utiliser cette API async du tout et de fournir votre propre mise en œuvre sur le dessus de l'API de synchronisation. Créez une tâche distincte pour chaque segment d'ID, soumettez-la à un pool de threads et enregistrez les contrats à terme dans une liste. Puis itérer sur eux et collecter tous les résultats. Il vous donnera plus de contrôle sur le niveau de concurrence, la gestion des exceptions et les délais pour une méthode d'api particulière que l'implémentation existante (AsyncTwitterImpl et DispatcherImpl) qui fournit un pool de threads fixe unique (avec seulement 1 thread par défaut) pour toutes les méthodes api, avale tous exceptions et ne fournit aucun délai d'expiration.