Czy uruchomione programy mogą uruchamiać się częściej niż co 10 sekund?

8

Mam takie usługi, które chciałbym uruchomić niemal natychmiast po zmodyfikowaniu plików.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>     
        <string>say</string>
        <string>a</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/username/Desktop/</string>
    </array>
</dict>
</plist>

Nawet jeśli ThrottleInterval był ustawiony na 1 lub 0, są one uruchamiane co najwyżej co 10 sekund.

9/9/12 4:57:05.457 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 7 seconds
9/9/12 4:57:09.541 PM com.apple.launchd.peruser.501[138]: (test) Throttling respawn: Will start in 3 seconds

man launchd.plist mówi tylko, że programy nie są uruchamiane domyślnie częściej niż co 10 sekund, ale nie wspomina, że ​​ThrottleInterval nie można ustawić poniżej tego.

ThrottleInterval <integer>
This key lets one override the default throttling policy imposed on jobs by launchd.
The value is in seconds, and by default, jobs will not be spawned more than once
every 10 seconds.  The principle behind this is that jobs should linger around just
in case they are needed again in the near future. This not only reduces the latency
of responses, but it encourages developers to amortize the cost of program invoca-
tion.

Możesz utrzymać działanie programu lub skryptu przez 10 sekund i obserwować zmiany co sekundę:

#!/bin/bash

start=$(date +%s)
prev=

until (( $(date +%s) >= $start + 10 )); do
    new=$(stat -f %m ~/Desktop/)
    [[ $prev != $new ]] && say a
    prev=$new
    sleep 1
done

Lub to samo w Ruby:

#!/usr/bin/env ruby

start = Time.now
prev = nil

until Time.now >= start + 10
  current = File.mtime("#{ENV['HOME']}/Desktop/")
  `say a` if current != prev
  prev = current
  sleep 1
end

Ale czy jest jakiś sposób na ominięcie lub skrócenie terminu? Dotyczy to również akcji folderów.

Lri
źródło

Odpowiedzi:

9

Nie ma możliwości ominięcia lub skrócenia limitu czasu.

Dokumentacja Apple dotycząca tworzenia uruchomionych zadań zawiera następujące informacje:

Ważne Jeśli demon wyłącza się zbyt szybko po uruchomieniu, uruchomiony może myśleć, że się zawiesił. Demony kontynuujące to zachowanie mogą zostać zawieszone i nie uruchomione ponownie, gdy nadejdą przyszłe żądania. Aby uniknąć tego zachowania, nie zamykaj systemu na co najmniej 10 sekund po uruchomieniu.

Twój program lub skrypt musi działać przez co najmniej 10 sekund. Rozważ zastosowanie pętli, aby sprawdzić daty modyfikacji plików w ciągu ostatnich dziesięciu sekund, spania przez dziesięć sekund i powtarzania.

Alternatywnie można oglądać określone pliki za pomocą interfejsów API kqueue lub FSEvent. To pytanie StackOverflow mogą być pomocne, na poziomie plików powiadomienie o zmianie systemu plików w systemie Mac OS X .

Graham Miln
źródło
2

Możesz zatrzymać skrypt w pętli, sprawdzając zmodyfikowane pliki, zamiast kończyć pracę po zakończeniu. Po sprawdzeniu zmodyfikowanych plików poczekaj kilka sekund. Jeśli znajdzie zmodyfikowane pliki, kontynuuj wykonywanie skryptu. Jeśli nie, śpij jeszcze raz.

Następnie uruchom uruchamiaj skrypt co x minut na wypadek śmierci poprzedniego uruchomienia. Kod na początku skryptu, aby sprawdzić, czy inna instancja już działa, a jeśli tak, to zamknij się.

Oprogramowanie Insomniac
źródło
uruchomienie nie wydaje się uruchamiać innej instancji, jeśli poprzednia nadal działa.
Lri
Uruchomione nie uruchomi wielu wystąpień tego samego zgłoszenia pracy.
Graham Miln,
1

Jeśli potrzebujesz uruchamiać skrypt częściej niż co 10 sekund, może to być kosztowne w kontekście „rozwidlenia” (czytaj: przydzielanie pamięci, uruchamianie nowych procesów itp.).

Dlatego w tym przypadku najlepiej jest napisać własnego „ demona ” (program, który działa w tle)

Polecam używać „bardziej wydajnego” języka jako BASH (moim ulubionym jest „perl”, ale ruby ​​też jest OK), ponieważ dobry demon obsługuje limity czasu, alarmy i tak dalej - rzeczy, które są zbyt trudne do implementacji w czystym bashu. (Oczywiście demon może również uruchamiać skrypty bash - w razie potrzeby). Podstawy to:

  • skrypt, który działa bez końca i czeka na jakieś zdarzenie. Zdarzeniem może być wejście sieciowe, prosty timer lub coś podobnego. Kiedy zdarzenie nadejdzie (np. Stan oczekiwania zakończony) skrypt zrobi co chcesz i cykl się powtórzy.

W świecie perla istnieją już moduły, które dostrajają twój skrypt jako proces „demona”, na przykład Proc :: Daemon . Nie mam doświadczenia z rubinem, ale ten artykuł może ci pomóc.

Możesz uruchomić proces demona za pomocą Launchd przy starcie systemu, aplikacji automatora podczas logowania lub ręcznie z Terminalu.

jm666
źródło