9
votes

Rake Vérifier si déjà en cours d'exécution

est-il possible d'exécuter une tâche de râteau que si elle ne fonctionne pas déjà, Je veux utiliser Cron pour exécuter des tâches de râteau, mais la tâche Rake ne devrait pas commencer si l'appel précédent n'est pas terminé. Merci


0 commentaires

5 Réponses :


5
votes

La solution générale spécifique sans rake à ceci est d'utiliser un fichier PID comme serrure. Vous envelopperiez la tâche Rake dans un script qui crée ce fichier lorsqu'il exécute un ratisser, le supprime lorsque Rake Finitions en marche et vérifie avant de commencer.

Je ne sais pas si Rake a quelque chose intégré, je ne sais rien.


2 commentaires

J'ai fait de telles choses avec PHP et 1 fois par mois Lock Fichier n'était pas supprimé ... Donc, je pense que ce n'est pas une solution à 100% pour cent


Si vous mettez le PID dans le fichier et vérifiez si cela fonctionne (plutôt que de l'existence du fichier), vous pourrez peut-être supprimer de manière plus fiable la serrure.



2
votes

Si vous souhaitez simplement ignorer cette tâche Rake, vous pouvez également utiliser la base de données pour stocker des informations sur la progression de la tâche (par exemple, mettre à jour un champ lorsque vous démarrez et terminez une tâche donnée) et vérifiez ces informations avant d'exécuter chaque tâche. < / p>

Cependant, si vous voulez un comportement semblable à la queue, vous voudrez peut-être envisager de créer un démon pour gérer les tâches. Le processus est très simple et vous donne beaucoup plus de contrôle. Il y a un très bon railscast à ce sujet: Démon personnalisé

L'approche du démon empêchera également l'environnement des rails d'être chargé à nouveau sur chaque tâche. Ceci est particulièrement utile si vos tâches de râteau sont fréquentes.


0 commentaires

13
votes

J'utilise Lockrun pour empêcher les tâches de cron d'exécuter plusieurs fois (cela ne fonctionne que lors de l'invocation la commande via la même invocation Lockrun , donc si vous devez vous protéger de divers chemins d'invocation, vous devez rechercher d'autres méthodes).

Dans votre crontab, vous l'invoquez comme ça : xxx


2 commentaires

Il y a aussi un troupeau (fréquemment in / usr / bin / troupeau) sur certains systèmes - la question n'a pas spécifié le système d'exploitation.


Un problème avec FLOCK est que vous ne pouvez pas exécuter une commande avec plus d'un argument, donc rake task_name est deux arguments et échoue donc.



10
votes

En outre, vous pouvez utiliser un verrouillage, mais le gérer dans la tâche:

def lockfile
  # Assuming you're running Rails
  Rails.root.join('tmp', 'pids', 'leads_task.lock')
end

def running!
  `touch #{lockfile}`
end

def done!
  `rm #{lockfile}`
end

def running?
  File.exists?(lockfile)
end

task :long_running do
  unless running?
    running!
    # long running stuff
    done!
  end
end


0 commentaires

1
votes

Voici ma variante avec la serrure de fichier pour rails Rake Tâches.

Mettez ceci dans votre fichier de tâche Rake (sous l'espace de noms, il ne se chevauche pas avec d'autres tâches Rake): P>

namespace :service do
  def cron_lock(name)
    path = Rails.root.join('tmp', 'cron', "#{name}.lock")
    mkdir_p path.dirname unless path.dirname.directory?
    file = path.open('w')
    return if file.flock(File::LOCK_EX | File::LOCK_NB) == false
    yield
  end

  desc 'description'
  task cleaning: :environment do
    cron_lock 'service_cleaning' do
      # your code
    end
  end
end


0 commentaires