ruby ou python

a marqué ce sujet comme résolu.

EDIT : par exemple, le […] C'est par exemple un peu plus difficile à faire en Java : il faut passer soit par des outils d'instrumentation de bytecode, soit définir ses propres annotations et utiliser l'APT, soit passer par une bibliothèque d'AOP ([…]

Les serveurs web en java, j'ai l'impression que c'est à peu près tous des usines à gaz par rapport à RoR, si on compte le JSP et tout ce qui va avec. Je n'ai jamais utilisé concrètement donc peut-être que je me trompe, mais c'est l'impression que ça me donne quand on va voir tout ce qu'il y a dedans, même juste un tomcat.

Ce que j'avais trouvé cool quand j'avais voulu testé RoR, c'est qu'on n'avais presque pas de configuration à faire si on définissait ses classes/méthodes/etc. selon un schéma préétabli.

IL y a deux trucs qui m'ont fait arrêter ruby assez tôt dans mon apprentissage en fait.

1° A l'époque je n'étais pas sur serveur dédié donc côté hébergement concret, impossible d'avoir autre chose que php à un prix abordable. Pour le coup, j'imagine que pour avoir python, c'est à peu près pareil. Ca a l'air de rien, mais si on fait un splendide site web mais qu'au final on ne peut pas le mettre en ligne....... bof… on a appris quelque chose mais pour quoi faire ?

2° Ca a peut-être changé maintenant, mais à un moment donné j'avais envie d'essayer de coder un truc rien à voir avec du web, et j'étais tombé sur un truc insoluble et totalement illogique/incohérent: un read sur un socket mettait en attente la totalité des threads de l'application. Ca m'avait complètement bloqué, je me suis dit que ruby c'était drôlement nul si on ne pouvait même pas faire ça. J'ose espérer qu'ils ont résolu çadepuis.

+0 -0

Ca m'avait complètement bloqué, je me suis dit que ruby c'était drôlement nul si on ne pouvait même pas faire ça. J'ose espérer qu'ils ont résolu ça depuis.

Ça sent le GIL.

Mauvaise nouvelle : c'est le cas de tous les interpréteurs du monde (ou presque : ça a récemment été résolu dans un fork de Pypy).

Bonne nouvelle : un appel système select() règle le problème du blocage en lecture tant qu'il n'y a rien à lire sur la socket (ou plus généralement un file handle quel qu'il soit). Il existe des wrappers et des modules pour ça en standard (voire carrément builtin) en Perl et en Python, donc très probablement aussi en Ruby.

+0 -0

Mauvaise nouvelle : c'est le cas de tous les interpréteurs du monde (ou presque : ça a récemment été résolu dans un fork de Pypy).

Ah, ça vient de quoi ?

Et alors pourquoi Java n'a jamais eu ce problème, même Java 1.0 ?

+0 -0

Hmm j'ai dit une connerie : les interpréteurs standard de Python et Ruby utilisent un GIL par choix. Ça leur permet de s'interfacer plus facilement avec des bibliothèques C (non thread safe).

Bref c'est normal qu'une socket se comporte de cette façon dans l'interpréteur standard Ruby. Il suffit d'en être conscient pour implémenter son soft en conséquence en monothread (i.e à coups de select dans une boucle pour faire l'ordonnancement à la main). L'un dans l'autre ça n'a pas de gros impact en perfs par rapport à du multithread GIL-free et monocoeur.

Par contre, très peu de cours/tutoriels abordent correctement ce sujet. C'est dommage parce que ça ne s'invente pas, et que beaucoup de débutants intéressés par la programmation réseau se retrouvent à faire leur apprentissage dans la douleur. Du coup il est prévu que ça figure dans le tuto Python qu'on est en train de rédiger. :)

+0 -0

Merci QuentinC pour tes retours.

Je ne vais pas digresser sur Java EE ici (même si mon point de vue rejoins à peu près le tiens à quelques exceptions près), et ton retour sur l'hébergement est bien entendu intéressant pour nous ramener les pieds sur terre.

A l'époque où je bossais avec RoR (ça date) il me semble qu'un site francophone listait les possibilités d'hébergement et c'était plutôt bien maintenu et organisé.

Merci en tout cas, j'aimerais pinger @artragis au cas où il puisse développer son message de la première page, ça m'intéresserait beaucoup (pour ma curiosité ;) ).

+0 -0

Tu es sûr que tu parles de moi et/ou de ce topic-ci?

Mon message de première page est :

le hype c'est un mot qui veut dire "un truc branché, à la mode, qui se veut moderne".

Python est assez simple à apprendre et te permet de faire de tout, la preuve tu es sur un site codé en python.

au niveau de django et Ror quel est le plus complet, le plus efficaces et rapides ?

Ce sont des fausses questions. Ils sont à peu près équivalents.

Bah y'a "à peu près" dans ton message qui m'intrigue un peu en réalité.

J'y peux rien, les petits points de détail qui font qu'un framework est ce qu'il est m'intéresse vachement, j'aime beaucoup comprendre comment certains points de détail sont implémentés dans pas mal de frameworks, parfois on trouve des trucs élégants.

Du coup, vu que tu sembles être le seul ici à avoir touché aux deux, un retour d'expérience sur ce "à peu près" m'intéresse pas mal. Après j'ai peut-être mal saisi ton message, dans ce cas : mes excuses.

+0 -0

Déjà, il y a le MVT de django qui diffère un peu du MVC qu'on trouve dans les Symfony, RoR ou ASP.NET MVC.

Je me suis mis à django pour zds, et je trouve que certains fichiers views.py sont un peu fouillis alors qu'il respectent plutôt bien les conventions (à quelques remarques prêt, qu'un ami de firm1 nous avait faite à une époque, faudrait les déterrer).

En vérité, je trouve le MVC web (donc RoR, Symfony, ASP.NET MVC) beaucoup plus rapide à appréhender que le MVT.

Je n'ai jamais codé avec RoR, j'ai juste vu quelques codes ruby à l'époque où je faisais quelque recherche sur l'état de l'art en ce qui concernait les manipulations de collections de données.
C'est à cette époque que j'ai compris que même les FilterIterator de PHP étaient bien faibles (en terme de perf, de quantité de code à produire …) que les listes d'intention Python, des extensions Linq de C# et même des manipulations de base qu'on pouvait faire avec ruby.

Le web, c'est un beau monde qui est souvent sous estimé parce qu'à un haut niveau d'abstraction, c'est une succession de CRUD pour le back et de bidouilles pour le front. Mais les framework sont vraiment des outils géniaux pour développer des applications.

RoR est django ont une très bonne page de debug, avec (dans les dernières capscreen que j'ai vu, après je sais pas comment ça a évolué) une petite préférence pour RoR, des outils de profiling puissants (là c'est Symfony qui qui gagne, je trouve, aussi bien pour la quantité de stat que pour l'utilisabilité de la page de profiling) et des intégrations intéressantes aux IDE pour toute la chaîne de production, du code au déploiement en passant par tous les types de tests. A ce jeu, c'est ASP.NET MVC qui gagne car Intellisense, webdeploy, le debugger CLR, les intégrations git/redmine/JIRA, les différentes intégration des outils de tests unitaires ou de charge sont vraiment immenses avec VS.

Donc pour mon expérience, c'est -en terme de ligne de codes produites, en ordre descendant- PHP vanilla, Symfony, ASP.NET MVC4, django, ASP.NET MVC 5. Ruby et RoR n'ont été que l'objet de recherches pour ma veille techno, pas de vraie séances de codage.

Par contre, très peu de cours/tutoriels abordent correctement ce sujet. C'est dommage parce que ça ne s'invente pas, et que beaucoup de débutants intéressés par la programmation réseau se retrouvent à faire leur apprentissage dans la douleur. Du coup il est prévu que ça figure dans le tuto Python qu'on est en train de rédiger.

Un moment donné, j'ai voulu me frotter à select en java, et c'était un peu le bordel. Mème en anglais, je n'ai pas trouvé de bon document expliquant sérieusement comment les sockets fonctionnaient avec ce système et comment il fallait faire.

IL faudrait peut-être un tutoriel indépendant du langage sur le sujet.

Je dois partir, je réagirai au reste plus tard.

+0 -0

Gros hors sujet, mais bon, puisque la question est posée :

Pour comprendre select(), étant donné que c'est un appel système POSIX à la base, le mieux reste encore de se renseigner sur le man (man 2 select). L'idée globale qu'on retrouve implémentée partout est simple. Indépendamment du langage ça prend cette forme :

1
select(read_fds, write_fds, except_fds, [timeout])

read_fds, write_fds, except_fds sont trois listes (éventuellement vides) de file descriptors (flux, sockets, whatever…) que l'on veut surveiller. L'appel à select retourne dès qu'une des conditions suivantes est remplie :

  • un fd de la liste read_fds est disponible en lecture (i.e. read() ne bloquera pas si on l'appelle dessus) ;
  • un fd de la liste write_fds est disponible en écriture ;
  • un fd de la liste except_fds est dans un état d'erreur ;
  • le timeout a été dépassé.

La fonction se démerde pour te retourner, d'une façon ou d'une autre1, trois listes de fd (readable, writable, error), pour t'indiquer lesquels sont prêts à l'instant T. Du coup, tu peux agir en conséquence dans ton code en sachant qu'aucun appel d'IO ne sera bloquant.

Le pattern classique est de faire une boucle infinie avec un select en tout début d'itération, puis d'appeler des callbacks qui vont bien sur tous les sockets/fichiers/flux retournés par select. Ça revient exactement à ordonnancer le traitement à la main, de manière à ce que ton programme ne soit jamais en train de bloquer sur une IO alors qu'une opération importante pourrait être faite pendant ce temps.

À côté de ça, sous Unix et dérivés, tu as un autre appel système (poll) qui revient à la même chose mais en évitant de devoir te taper trois listes à la fois puisque tu lui passes une liste de paires (fd, watched_events). En général, les langages à plus haut niveau vont te wrapper ça dans un objet dans lequel tu enregistres les fd à surveiller, et dont un simple appel à la méthode poll([timeout]) te retournera une liste de paires (fd, event) pour te signaler les fd disponibles. C'est la même fonctionnalité, mais en plus clean. En fait, elle est à préférer sur les unixoïdes, parce qu'elle est également plus performante. :)


  1. L'appel-système modifie les trois listes en place et retourne un entier qui indique le nombre total de descripteurs prêts, i.e. il retourne 0 en cas de timeout. Mais en Python, par exemple, il retourne directement un triplet de listes. 

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte