2010-04-26 4 views
1

J'ai une application Sinatra qui prend essentiellement des valeurs d'entrée et trouve ensuite les données correspondant à ces valeurs des services externes tels que Flickr, Twitter, etc.Demandes Web simultanées avec Ruby (Sinatra?)?

Par exemple:

entrée: "Chattanooga Choo Choo" Would sortir et trouver des images à Flickr sur Chattanooga Choo Choo et tweets de Twitter, etc.

en ce moment j'ai quelque chose comme:

@images = Flickr::...find...images.. 

@tweets = Twitter::...find...tweets... 

@results << @images 

@results << @tweets 

S Ma question est la suivante: Existe-t-il un moyen efficace pour Ruby de traiter ces demandes simultanément? Au lieu d'attendre que les images se terminent avant la fin des tweets.

Répondre

2

Les threads fonctionneraient, mais c'est un outil grossier. Vous pouvez essayer quelque chose comme ceci:

flickr_thread = Thread.start do 
    @flickr_result = ... # make the Flickr request 
end 

twitter_thread = Thread.start do 
    @twitter_result = ... # make the Twitter request 
end 

# this makes the main thread wait for the other two threads 
# before continuing with its execution 
flickr_thread.join 
twitter_thread.join 

# now both @flickr_result and @twitter_result have 
# their values (unless an error occurred) 

Vous auriez à bricoler un peu avec le code cependant, et ajouter la détection d'erreur appropriée. Je ne me souviens pas maintenant si les variables d'instance fonctionnent lorsqu'elles sont déclarées dans le bloc de threads, les variables locales ne le feraient pas à moins qu'elles aient été explicitement déclarées en dehors. Je ne dirais pas que c'est une solution élégante, mais je pense que cela fonctionne, et ce n'est pas trop complexe. Dans ce cas, il n'y a heureusement pas besoin de verrouillage ou de synchronisation en dehors des jointures, donc le code se lit plutôt bien. Peut-être un outil comme EventMachine (en particulier le sous-projet em-http-request) pourrait vous aider, si vous faites beaucoup de choses comme ça. Cela pourrait probablement faciliter le codage à un niveau supérieur. Les threads sont difficiles à obtenir correctement.

+0

Merci. J'aime cette approche pour ce que j'essaie de faire. Je vais vous donner un coup de feu. Merci à tout le monde. – cbmeeks

1

Oui pourquoi pas les discussions?

Comme je l'ai compris. Dès que l'utilisateur soumet un formulaire, vous voulez traiter toutes les demandes en parallèle non? Vous pouvez avoir un contrôleur multithread (le support des threads Ruby fonctionne vraiment bien.) Où vous recevez une requête, puis vous exécutez en parallèle les services de requêtes externes et ensuite vous répondez en une réponse ou du côté client vous envoyez un post ajax pour chaque service et processus (peut-être chaque service externe a votre propre contrôleur/actions?)

2

Vous pouvez envisager d'effectuer une modification côté client pour utiliser des requêtes Ajax asynchrones afin d'obtenir chaque type (image, twitter) indépendamment. Le problème avec les threads du serveur (l'un d'entre eux de toute façon) est que si un service se bloque, la demande entière se bloque en attente de ce thread pour terminer. Avec Ajax, vous pouvez charger une section d'images, une section twitter, etc., et si l'un d'eux se bloque, les autres afficheront toujours leurs résultats. Finalement, vous pouvez expirer les demandes et montrer une baleine défaillante ou quelque chose dans cette section seulement.

+0

Je seconde ce point, il suffit d'avoir différents points de terminaison d'URL pour chaque service, puis appelez tous avec AJAX – MatthewFord

1

Envisagez d'utiliser YQL pour cela. Il supporte les sous-requêtes, de sorte que vous pouvez tirer tout ce dont vous avez besoin avec un seul appel (côté client, pair) qui crache simplement JSON de ce que vous avez besoin de rendre. Il existe déjà des tonnes de tutoriels.

+0

C'est une idée intéressante. Je n'avais pas pensé à ça. – cbmeeks

+0

Veuillez développer le lien URL raccourci. –

Questions connexes