Jarayonlar
Kirish
Goravel Go'ning standart os/exec paketi atrofida ifodali va oqlangan API taqdim etadi, bu sizga ilovangizdan tashqi buyruqlarni muammosiz chaqirish imkonini beradi. Odatiy bo'lib, Go'ning jarayonlarni boshqarishi batafsil bo'lishi mumkin; Goravel'ning "Jarayon" jabhasi bu umumiy vazifani soddalashtiradi, buyruqlarni bajarish, chiqishlarni boshqarish va asinxron jarayonlarni boshqarish uchun ravon interfeysni taklif qiladi.
Jarayonlarni chaqirish
Ishlayotgan jarayonlar
Jarayonni ishga tushirish uchun siz "Run" yoki "Start" usullaridan foydalanishingiz mumkin. Run metodi buyruqni bajaradi va uning tugashini kutadi, Start metodi esa jarayonni asinxron ravishda ishga tushiradi va boshqaruvni darhol qaytaradi.
Bloklash buyrug'ini quyidagicha bajarishingiz mumkin:
import (
"fmt"
"goravel/app/facades"
)
func main() {
result := facades.Process().Run("echo", "Hello, World!")
if result.Failed() {
panic(result.Error())
}
fmt.Println(result.Output())
}Agar siz satr buyrug'ini to'g'ridan-to'g'ri (argumentlarga ajratmasdan) ishga tushirmoqchi bo'lsangiz, uni Run ga bitta satr sifatida uzatishingiz mumkin, buning uchun /bin/sh -c (Linux/macOS) yoki cmd/C (Windows) ishlatiladi. E'tibor bering, mexanizm faqat satr buyrug'i bo'shliqlar yoki &, |, - belgilarini o'z ichiga olganda ishga tushirilishi mumkin.
result := facades.Process().Run("echo Hello, World!")
// /bin/sh -c ""echo Hello, World!"" on Linux/macOS
// cmd /c "echo Hello, World!" on WindowsRun usuli Result interfeysini qaytaradi. "Result" interfeysi sizga buyruqning chiqishi va holatiga qulay kirish imkonini beradi:
result := facades.Process().Run("ls", "-la")
result.Command() // string: Asl buyruq
result.Error() // error: Buyruq bajarilishi natijasida qaytarilgan xato
result.ErrorOutput() // string:Stderr dan chiqish
result.ExitCode() // int: Chiqish kodi (masalan, 0, 1)
result.Failed() // bool: Agar chiqish kodi 0 bo'lmasa, rost
result.Output() // string: Stdout dan chiqishJarayon parametrlari
Ko'pincha buyruq qanday ishlashini, masalan, qayerda ishlashini yoki qanday muhit o'zgaruvchilarini ko'rishini sozlashingiz kerak bo'ladi. "Process" jabhasi buning uchun ravon API taqdim etadi.
Path
Buyruq uchun ishchi katalogni ko'rsatish uchun Path usulidan foydalanishingiz mumkin. Agar buni o'rnatmasangiz, jarayon ilovangizning joriy ishchi katalogida bajariladi.
result := facades.Process().Path("/var/www/html").Run("ls", "-la")Timeout
Jarayonning cheksiz vaqt davomida to'xtab qolishining oldini olish uchun siz tanaffusni amalga oshirishingiz mumkin. Agar jarayon belgilangan vaqtdan uzoqroq davom etsa, u o'chiriladi.
import "time"
result := facades.Process().Timeout(10 * time.Minute).Run("sleep", "20")Atrof-muhit o'zgaruvchilari
Siz maxsus muhit o'zgaruvchilarini jarayonga Env usuli yordamida o'tkazishingiz mumkin. Jarayon shuningdek, tizimning muhit o'zgaruvchilarini meros qilib oladi.
// FOO=BAR ni mavjud tizim envslari bilan birga o'tkazadi.
result := facades.Process().Env(map[string]string{
"FOO": "BAR",
"API_KEY": "secret",
}).Run("printenv")Kirish (Stdin)
Agar sizning buyrug'ingiz standart inputdan (stdin) kirishni kutsa, uni "Input" usuli yordamida taqdim etishingiz mumkin. Bu "io.Reader" ni qabul qiladi.
import "strings"
// Cat buyrug'iga "Salom Goravel" deb javob beradi
result := facades.Process().
Input(strings.NewReader("Hello Goravel")).
Run("cat")Jarayon chiqishi
Jarayon natijasiga natija obyektidagi Output (standart chiqish) va ErrorOutput (standart xato) usullari yordamida bajarilgandan so'ng kirishingiz mumkin.
result := facades.Process().Run("ls", "-la")
fmt.Println(result.Output())
fmt.Println(result.ErrorOutput())Agar siz chiqishni real vaqt rejimida (oqimli) qayta ishlashingiz kerak bo'lsa, "OnOutput" usuli yordamida qayta qo'ng'iroqni ro'yxatdan o'tkazishingiz mumkin. Qayta qo'ng'iroq ikkita argumentni oladi: chiqish turi (stdout yoki stderr) va chiqish ma'lumotlarini o'z ichiga olgan bayt bo'lagi.
import (
"fmt"
"github.com/goravel/framework/contracts/process"
)
result := facades.Process().OnOutput(func(typ process.OutputType, b []byte) {
// Bu yerda real vaqt rejimida translyatsiyani boshqaring
fmt.Print(string(b))
}).Run("ls", "-la")Agar siz faqat bajarilgandan keyin chiqishda ma'lum bir satr borligini tekshirishingiz kerak bo'lsa, siz SeeInOutput yoki SeeInErrorOutput yordamchi usullaridan foydalanishingiz mumkin.
result := facades.Process().Run("ls", "-la")
if result.SeeInOutput("go.mod") {
// The file exists
}Jarayon chiqishini o'chirib qo'yish
Agar jarayoningiz katta hajmdagi ma'lumotlarni yozsa, uni qanday saqlashni boshqarishingiz mumkin.
Quietly dan foydalanish chiqish ma'lumotlarining konsolga yoki bajarilish vaqtida jurnallarga pufakchalar bilan chiqishining oldini oladi, ammo ma'lumotlar hali ham to'planadi va result.Output() orqali mavjud bo'ladi.
Agar siz yakuniy natijaga umuman kirishingiz shart bo'lmasa va xotirani tejashni istasangiz, "DisableBuffering" dan foydalanishingiz mumkin. Bu natija natija obyektida saqlanishiga to'sqinlik qiladi, garchi siz hali ham oqimni real vaqt rejimida "OnOutput" yordamida tekshirishingiz mumkin.
// Chiqishni yozib oladi, lekin bajarish paytida chop etmaydi
facades.Process().Quietly().Run("...")
// Chiqishni yozib olmaydi (xotirani tejaydi), lekin oqimli uzatishga imkon beradi
facades.Process().DisableBuffering().OnOutput(func(typ process.OutputType, b []byte) {
// ...
}).Run("...")Quvurlar
Ba'zan siz bir jarayonning chiqishini boshqa jarayonning kirishiga o'tkazishingiz kerak bo'ladi. Process fasadi buni Pipe usuli yordamida osonlashtiradi, bu sizga bir nechta buyruqlarni sinxron ravishda birlashtirish imkonini beradi.
import "github.com/goravel/framework/contracts/process"
result := facades.Process().Pipe(func(pipe process.Pipe) {
pipe.Command("echo", "Hello, World!")
pipe.Command("grep World") // string command: /bin/sh -c "grep World"
pipe.Command("tr", "a-z", "A-Z")
}).Run()WARNING
Timeout, Env yoki Input kabi jarayon parametrlari Pipe usuli chaqirilgandan keyin sozlanishi kerak. Pipe chaqiruvidan oldin qo'llanilgan har qanday konfiguratsiya e'tiborga olinmaydi.
// To'g'ri: Quvurdan keyin konfiguratsiya qo'llanildi
facades.Process().Pipe(...).Timeout(10 * time.Second).Run()
// Noto'g'ri: Vaqt tugashi e'tiborga olinmaydi
facades.Process().Timeout(10 * time.Second).Pipe(...).Run()Quvur liniyasi chiqishi va kalitlari
Siz quvur liniyasining chiqishini real vaqt rejimida "OnOutput" usuli yordamida tekshirishingiz mumkin. Quvur bilan ishlatilganda, qayta chaqiruv imzosi kalit (satr) ni o'z ichiga oladi, bu sizga qaysi buyruq natijani berganini aniqlash imkonini beradi.
Odatiy bo'lib, key buyruqning raqamli indeksidir. Biroq, murakkab quvurlarni nosozliklarni tuzatish uchun juda foydali bo'lgan As usuli yordamida har bir buyruqqa o'qiladigan yorliq tayinlashingiz mumkin.
facades.Process().Pipe(func(pipe process.Pipe) {
pipe.Command("cat", "access.log").As("source")
pipe.Command("grep", "error").As("filter")
}).OnOutput(func(typ process.OutputType, line []byte, key string) {
// 'key' will be "source" or "filter"
}).Run()Asinxron jarayonlar
Run usuli jarayon tugashini kutayotgan bir paytda, Start usuli jarayonni asinxron ravishda ishga tushirish uchun ishlatilishi mumkin. Bu sizning ilovangiz boshqa vazifalarni bajarishda davom etayotgan paytda jarayonning fonda ishlashiga imkon beradi. Start usuli Running interfeysini qaytaradi.
import "time"
running, err := facades.Process().Timeout(10 * time.Second).Start("sleep", "5")
// Boshqa ishlarni davom ettiring...
result := running.Wait()Jarayon bloklanmasdan tugaganligini tekshirish uchun siz Done usulidan foydalanishingiz mumkin. Bu jarayon tugaganda yopiladigan standart Go kanalini qaytaradi, bu esa uni select operatorlarida foydalanish uchun ideal qiladi.
running, err := facades.Process().Start("sleep", "5")
select {
case <-running.Done():
// Jarayon muvaffaqiyatli yakunlandi
case <-time.After(1 * time.Second):
// Agar juda ko'p vaqt talab etilsa, maxsus mantiq
}
result := running.Wait()WARNING
Bajarilganlikni aniqlash uchun Done kanalidan foydalansangiz ham, keyinroq Wait() funksiyasini chaqirishingiz kerak. Bu jarayonning operatsion tizim tomonidan to'g'ri "reaped" va asosiy resurslarni tozalashini ta'minlaydi.
Jarayon identifikatorlari va signallari
Siz PID usuli yordamida ishlayotgan jarayon uchun operatsion tizimning jarayon identifikatorini (PID) olishingiz mumkin.
running, err := facades.Process().Start("ls", "-la")
println(running.PID())Signallarni yuborish
Goravel jarayonning hayot aylanishi bilan o'zaro ta'sir qilish usullarini taqdim etadi. Siz Signal usuli yordamida ma'lum bir OS signalini yuborishingiz yoki Stop yordamchisidan foydalanib, nafis o'chirishga harakat qilishingiz mumkin.
Stop usuli ayniqsa foydalidir: u avval tugatish signalini yuboradi (standart holatda SIGTERM ga o‘rnatiladi). Agar jarayon belgilangan vaqt ichida tugamasa, u majburan o'chiriladi (SIGKILL).
import (
"os"
"time"
)
running, err := facades.Process().Start("sleep", "60")
// Signalni qo'lda yuborish
running.Signal(os.Interrupt)
// Nafislik bilan to'xtashga harakat qiling, 5 soniya kuting, keyin majburan o'ldiring
running.Stop(5 * time.Second)Jarayon holatini tekshirish
Jarayonning joriy holatini Running usuli yordamida tekshirishingiz mumkin. Bu, birinchi navbatda, nosozliklarni tuzatish yoki sog'liqni tekshirish uchun foydalidir, chunki u jarayon hozirda faol yoki yo'qligini ko'rsatadi.
// Snapshot tekshiruvi (jurnallar yoki ko'rsatkichlar uchun foydali)
agar running.Running() {
fmt.Println("Jarayon hali ham faol...")
}TIP
Agar jarayon tugashi bilan kodni ijro etish kerak bo'lsa, Running() funksiyasini so'ramang. Buning o'rniga, holatni qayta-qayta tekshirishdan ko'ra ancha samaraliroq bo'lgan Done() kanali yoki Wait() usulidan foydalaning.
Bir vaqtning o'zida sodir bo'ladigan jarayonlar
Goravel bir vaqtning o'zida bir nechta buyruqlarni bajarish imkonini beruvchi bir vaqtning o'zida bir nechta jarayonlarni boshqarishni osonlashtiradi. Bu, ayniqsa, ommaviy ishlov berish yoki mustaqil vazifalarni parallel ravishda bajarish uchun foydalidir.
Hovuzlarni bajarish
Jarayonlar pulini ishga tushirish uchun siz Pool usulidan foydalanishingiz mumkin. Bu siz bajarmoqchi bo'lgan buyruqlarni belgilaydigan yopilishni qabul qiladi.
Odatiy bo'lib, Pool usuli barcha jarayonlarning tugashini kutadi va jarayon nomi (yoki indeksi) bilan belgilangan natijalar xaritasini qaytaradi.
results, err := facades.Process().Pool(func(pool process.Pool) {
pool.Command("sleep", "1").As("first")
pool.Command("sleep 2").As("second") // string command: /bin/sh -c "sleep 2"
}).Run()
if err != nil {
panic(err)
}
// Natijalarga tayinlangan kalit orqali kirish
println(results["first"].Output())
println(results["second"].Output())Nomlash jarayonlari
Odatiy bo'lib, hovuzdagi jarayonlar ularning raqamli indekslari (masalan, "0", "1") bilan belgilanadi. Biroq, natijalarga aniqlik kiritish va osonroq kirish uchun har bir jarayonga As usuli yordamida noyob nom berishingiz kerak:
pool.Command("cat", "system.log").As("system")Pool imkoniyatlari
Pool quruvchisi butun partiyaning bajarilish xatti-harakatlarini boshqarish uchun bir nechta usullarni taqdim etadi.
Concurrency
Siz Concurrency usuli yordamida bir vaqtning o'zida ishlaydigan jarayonlarning maksimal sonini boshqarishingiz mumkin.
facades.Process().Pool(func(pool process.Pool) {
// 10 ta buyruqni aniqlang...
}).Concurrency(2).Run()Umumiy vaqt tugashi (Total Timeout)
Siz Timeout usuli yordamida butun hovuz bajarilishi uchun global vaqtni belgilashingiz mumkin. Agar hovuz bu vaqtdan ko'proq vaqt talab qilsa, barcha ishlayotgan jarayonlar to'xtatiladi.
facades.Process().Pool(...).Timeout(1 * time.Minute).Run()Asinxron hovuzlar
Agar ilovangiz boshqa vazifalarni bajarayotgan paytda hovuzni fonda ishga tushirishingiz kerak bo'lsa, Run o'rniga "Ishga Start usulidan foydalanishingiz mumkin. Bu RunningPool deskriptorini qaytaradi.
runningPool, err := facades.Process().Pool(func(pool process.Pool) {
pool.Command("sleep", "5").As("long_task")
}).Start()
// Hovuz hali ham ishlayotganini tekshiring
if runningPool.Running() {
fmt.Println("Pool is active...")
}
// Barcha jarayonlar tugashini kuting va natijalarni to'plang
results := runningPool.Wait()Running Pools bilan o'zaro aloqa
RunningPool interfeysi faol hovuzni boshqarishning bir nechta usullarini taqdim etadi:
PIDs(): Buyruq nomi bilan belgilangan jarayon identifikatorlari xaritasini qaytaradi.Signal(os.Signal): Hovuzdagi barcha ishlayotgan jarayonlarga signal yuboradi.Stop(timeout, signal): Barcha jarayonlarni nafislik bilan to'xtatadi.Done(): Hovuz tugagach yopiladigan kanalni qaytaradi, buselectoperatorlari uchun foydali.
select {
case <-runningPool.Done():
// Barcha jarayonlar tugadi
case <-time.After(10 * time.Second):
// Agar barcha jarayonlar juda uzoq davom etsa, ularni majburan to'xtatish
runningPool.Stop(1 * time.Second)
}Pool Output
Siz OnOutput usuli yordamida real vaqt rejimida hovuzning chiqishini tekshirishingiz mumkin.
WARNING
OnOutput qayta chaqiruvi bir vaqtning o'zida bir nechta goroutinlardan chaqirilishi mumkin. Qayta qo'ng'iroq qilish mantig'ingiz ish zarrachalaridan himoyalanganligiga ishonch hosil qiling.
facades.Process().Pool(func(pool process.Pool) {
pool.Command("ping", "google.com").As("ping")
}).OnOutput(func(typ process.OutputType, line []byte, key string) {
// kalit "ping" bo'ladi
fmt.Printf("[%s] %s", key, string(line))
}).Run()Jarayon bo'yicha konfiguratsiya
Hovuz ta'rifi ichida har bir buyruq yakka jarayonlarga o'xshash individual konfiguratsiya usullarini qo'llab-quvvatlaydi:
Path(string): Ishchi katalogni o'rnatadi.Env(map[string]string): Muhit o'zgaruvchilarini o'rnatadi.Input(io.Reader): Standart kiritishni o'rnatadi.Timeout(time.Duration): Muayyan buyruq uchun vaqtni belgilaydi.Quietly(): Ushbu maxsus buyruq uchun chiqish yozib olishni o'chiradi.DisableBuffering(): Xotira buferlashni o'chiradi (yuqori hajmli chiqish uchun foydali).
facades.Process().Pool(func(pool process.Pool) {
pool.Command("find", "/", "-name", "*.log").
As("search").
Path("/var/www").
Timeout(10 * time.Second).
DisableBuffering()
}).Run()