2010-04-13 14 views
2

J'ai une architecture de maître-ouvrier où le nombre de travailleurs augmente chaque semaine. Je ne peux plus m'attendre à ce que SSH ou console à distance dans chaque machine pour tuer le travailleur, faire une synchronisation de contrôle de source, et redémarrer. J'aimerais que le maître mette un message sur le réseau pour que chaque machine synchronise et redémarre.Est-ce qu'un script Ruby autonome (windows et mac) peut être rechargé et redémarré?

C'est là que j'ai franchi un barrage routier. Si j'utilisais une plate-forme saine, je pourrais juste faire:

exec('ruby', __FILE__) 

... et être fait. Cependant, je l'ai fait le test suivant:

p Process.pid 
sleep 1 
exec('ruby', __FILE__) 

... et sur Windows, je reçois une instance ruby ​​pour chaque appel à exec. Aucun d'entre eux ne meurt jusqu'à ce que j'atteigne^C sur la fenêtre en question. Sur chaque plate-forme, j'ai essayé, il exécute la nouvelle version du fichier à chaque fois, ce que j'ai vérifié en faisant des modifications simples au script de test pendant que le test marchait le long.

La raison pour laquelle j'imprime le pid est de vérifier le comportement que je vois. Sur Windows, j'obtiens un pid différent à chaque exécution - ce à quoi je m'attendrais, étant donné que je vois un nouveau processus dans le gestionnaire de tâches pour chaque exécution. Le mac se comporte correctement: le pid est le même pour chaque appel système et j'ai vérifié avec dtrace que chaque exécution est en train de déclencher un appel à l'appel système syscall. Donc, en bref, existe-t-il un moyen d'obtenir un script windows ruby ​​pour redémarrer son exécution afin qu'il exécute tout code - y compris lui-même - qui a changé pendant son exécution? S'il vous plaît noter que ce n'est pas une application de rails, même si elle utilise activerecord.

+0

Si je comprends bien, il y a 2 problèmes, un, il n'y a aucun moyen que vous pouvez signaler le processus maître sous Windows pour déclencher le redémarrage de lui-même. Le second, est que lorsque "exec" est effectué, ne prend pas le code mis à jour. Pouvez-vous confirmer cela? –

Répondre

2

Après avoir essayé plusieurs solutions (y compris celui présenté par Byron Whitlock, qui a finalement m'a mis sur le chemin d'une fin satisfaisante) je me suis installé sur:

IO.popen("start cmd /C ruby.exe #{$0} #{ARGV.join(' ')}") 
sleep 5 

je trouve que si je ne l'ai pas dormez du tout après le popen, et juste sorti, le spawn échouerait fréquemment (> 50% du temps). Ce n'est pas multi-plateforme évidemment, de sorte afin d'avoir le même comportement sur le mac:

IO.popen("xterm -e \"ruby blah blah blah\"&") 
+1

Je l'ai eu pour travailler sur Ubuntu: 'IO.popen (" kill # {Process.pid} && ruby ​​server.rb & ")'. Je pense que la partie xterm/sleep n'est pas nécessaire si vous tuez votre processus de la popen. – inket

0

La manière classique de redémarrer un programme consiste à en écrire un autre qui le fait pour vous. donc vous lancez un processus à restart.exe <args>, puis mourez ou quittez; restart.exe attend que le script appelant ne soit plus en cours d'exécution, puis redémarre le script.

+0

J'espérais éviter cette situation si possible. Le script en question est déjà un nouveau modèle pour les scripts qui font le vrai travail. C'était nécessaire pour contourner les limitations de ruby ​​sur les fenêtres face aux scripts qui appellent d'autres applications (comme Visual Studio.) Si je peux éviter d'avoir un starter appeler un starter qui appelle un travailleur, je serais beaucoup plus heureux. En outre - cela ne réglerait pas entièrement le problème: que se passe-t-il si je change le code du démarreur de haut niveau? J'ai seulement déplacé le problème d'une couche sans réellement le résoudre. – Sniggerfardimungus