2009-07-24 6 views
1

Je suis actuellement confronté à un problème avec ActiveResource: lorsqu'un nom d'hôte est résolu pour une requête ActiveResource, mais qu'aucun serveur à l'autre extrémité ne renvoie d'informations, la valeur de délai d'ActiveResource ne fonctionne pas. La demande se bloque simplement. Après avoir examiné le code ActiveResource, j'ai réalisé que c'était parce que l'objet Net: Http sous-jacent a seulement une valeur de timeout définie: read_timeout. La bibliothèque Net: Http définit cela comme "Secondes à attendre jusqu'à la lecture d'un bloc (par un appel read (2))". Le Net: Http lib définit également une autre valeur de délai, open_timeout, qui est définie comme "secondes à attendre jusqu'à ce que la connexion est ouverte". Je ne suis pas sûr pourquoi open_timeout n'est pas défini par défaut avec la valeur de délai d'attente définie sur une classe ActiveResource, mais après avoir modifié la classe ActiveResource :: Connection pour inclure open_timeout sur les objets http, mon problème a été résolu! Je suis nouveau sur les rails, donc je ne suis pas sûr de la meilleure façon de faire cette modification dans mon projet; Je ne veux pas juste changer le code dans mon répertoire de gemme. Existe-t-il un moyen approprié de réaliser ces modifications dans un projet de rails? J'ai vu qu'il est possible de charger des classes de rails à partir du dossier/vendor, mais doivent-ils tous être là pour que ça fonctionne? J'ai commencé à créer des sous-classes des classes ActiveResource :: Base et ActiveResource :: Connection, mais il semblait qu'il y avait un moyen plus simple de le faire, car la fonction qui crée l'instance Net: Http est privée ... des pensées?Surcharge/Modification de la classe Rails (ActiveResource)

Répondre

3

Tout d'abord, il est une question que vous devez signaler à Rails de l'bugtracker: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/

Quand je dois du correctif des choses mineures comme celles-ci, je crée généralement un fichier initialiseur dans RAILS_ROOT/config/initializers et rouvrir la classe que j'ai l'intention de réparer.

class ActiveResource::Base 
    # your fix goes here 
end 

Ceci est appelé patch de singe et est quelque peu controversé. Mais je considère personnellement qu'il est assez brutal d'introduire un nouveau niveau dans la hiérarchie d'héritage qui n'a pas de signification sémantique pour mon code.

+0

Merci pour l'aide - c'est exactement ce que je voulais! – Ben

+0

Par leur façon - je suis curieux de savoir pourquoi exactement cela fonctionne? La méthode que je substitue dans la classe initializers est une méthode privée dans la classe ActiveResource :: Connection - et pourtant cela semble fonctionner sans problème? Je peux trouver peu d'informations sur la façon dont les fichiers du dossier d'initialisation affectent les classes de rails principaux. Les fichiers d'initialisation – Ben

+0

ne sont en aucun cas spéciaux. Leur contenu est simplement exécuté après le chargement de l'environnement. En Ruby, rien ne vous empêche de rouvrir une classe et de jouer avec des parties intimes. Une visibilité des méthodes est un concept assez superficiel dans Ruby. Vous pouvez par exemple appeler une méthode privée sur un objet avec obj.send (: private_method, ...) – flitzwald

Questions connexes