11. Servis (daemon) uygulaması
Servis, başlatılıp durdurulana kadar çalışan bir programdır: bir sistem
ajanı, bir izleyici, bir kuyruk tüketicisi. KabaLang'de servis "ad": bloğu
bunun yaşam döngüsünü tanımlar.
Hazır iskelet: kabalang yeni <ad> --servis
(13. sayfa).
Bu sayfadaki servis örnekleri belge testinde derlenir; biri ayrıca şablon testinde gerçekten başlatılıp SIGTERM ile düzgün durdurulur (çıkış kodu 0 ölçülür).
Üç kancalı iskelet
kullan kaba.sistem
tur = 0
servis "kaba-nabiz":
baslarken:
gunluk.bilgi("servis başlıyor")
calisirken:
iken servis.calisiyor_mu():
tur = tur + 1
gunluk.bilgi(f"nabız {tur}")
eger degil servis.uyu(5000):
kir
dururken:
gunluk.bilgi(f"{tur} turdan sonra kapandı ({servis.durdurma_nedeni()})")| Kanca | Ne zaman çalışır |
|---|---|
baslarken: |
bir kez, ana gövdeden önce — kaynakları açın |
calisirken: |
ana gövde; durdurulana kadar döner |
dururken: |
SIGTERM/SIGINT geldiğinde — kaynakları bırakın |
Servis çalışırken pid kilidi tutar, günlüğe düzeyli yazar ve sinyal
geldiğinde dururken kancasını çalıştırıp 0 çıkış koduyla kapanır.
Üç tuzak — üçü de ölçülmüştür
1. servis.uyu() dönüşünü denetleyin
kullan kaba.sistem
servis "kaba-dogru-uyku":
calisirken:
iken servis.calisiyor_mu():
gunluk.bilgi("tur")
eger degil servis.uyu(5000): # yanlis → "dur" demektir
kirservis.uyu(ms) sinyal gelirse anında uyanır ve yanlis döner. Dönüşü
yok sayan döngü SIGTERM'i duymaz; systemd TimeoutStopSec sonunda SIGKILL
atar ve dururken kancası hiç çalışmaz — kaynaklar bırakılmadan ölürsünüz.
2. Döngü koşulu servis.calisiyor_mu() olmalı
iken dogru: yazarsanız program yalnız öldürülerek durur. calisiyor_mu()
durdurma isteğini görür.
3. uyu() değil servis.uyu()
Sıradan uyu(ms) sinyalle uyanmaz: kapanma tam bir uyku süresi gecikir.
Servis içinde her zaman servis.uyu(ms) yazın.
Servis API'si
| Çağrı | Ne yapar |
|---|---|
servis.calisiyor_mu() |
durdurma istendi mi (döngü koşulu) |
servis.uyu(ms) |
sinyale duyarlı uyku; yanlis = dur |
servis.durdurma_nedeni() |
hangi sinyalle durdu |
servis.durdur_iste() |
programın kendisi durmak isterse |
Ayrıca sistemdeki başka birimleri yönetmek için:
servis.baslat("sshd") · servis.durdur(...) · servis.yeniden_baslat(...) ·
servis.durum(...) · servis.aktif_mi(...).
⚠️ Aynı ada sahip iki kopya aynı anda çalışamaz: servis adı bir pid
kilidi (/run/user/<uid>/<ad>.pid) tutar. Bu bilerek böyledir — iki kopya
aynı kaynağı bozmasın.
Çıktı nereye gider: gunluk, yazdir değil
Servis çıktısını gunluk.* ile yazın. yazdir kullanıcıya konuşur;
gunluk düzeyiyle birlikte systemd günlüğüne düşer, journalctl -p err
gibi süzmeler çalışır.
systemd birimi üretmek
kabalang birim ana.kbl --kullanici-birimi
systemctl --user daemon-reload
systemctl --user enable --now <servis-adi>
journalctl --user -u <servis-adi> -fSistem geneli birim için --kullanici-birimi yazmayın; --calistiran <kullanici>
ile hangi hesapla koşacağını belirtin.
⚠️ servis "ad": bloğu olmayan bir programdan birim üretilmez; komut
hata verir. Sebebi ölçülmüştür: böyle bir program açılır açılmaz biter,
systemd onu ya sonsuza kadar yeniden başlatır ya da "başarıyla bitti" diye
pasife çeker — kullanıcı bunu ancak günlüğe bakınca fark eder. Bilerek
istiyorsanız --zorla verin.
Dosyaya nabız yazan tam örnek
kullan kaba.sistem
nabiz_dosyasi = "/tmp/kabalang-nabiz.log"
tur = 0
servis "kabalang-nabiz":
baslarken:
gunluk.bilgi(f"nabız dosyası: {nabiz_dosyasi}")
dosya.yaz(nabiz_dosyasi, "")
calisirken:
iken servis.calisiyor_mu():
tur = tur + 1
yuk = sistem.cpu_kullanim()
ram = sistem.ram_yuzde()
dosya.ekle(nabiz_dosyasi, f"{tur} cpu=%{yuk} ram=%{ram}\n")
eger yuk > 90:
gunluk.uyari(f"işlemci yükü yüksek: %{yuk}")
degilse:
gunluk.bilgi(f"nabız {tur} · cpu %{yuk} · ram %{ram}")
eger degil servis.uyu(5000):
kir
dururken:
dosya.ekle(nabiz_dosyasi, f"kapandi tur={tur}\n")
gunluk.bilgi(f"{tur} turdan sonra düzgün kapandı ({servis.durdurma_nedeni()})")