> ## Documentation Index
> Fetch the complete documentation index at: https://ziva.zeleza.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Gelişmiş Kuyruk Rehberi

> Koşullu akışlar, dinamik görev üretimi ve dayanıklı yeniden denemeler

# Gelişmiş Kuyruk Rehberi

Aşağıdaki örnekler Ziva ile karmaşık iş akışlarını nasıl düzenleyebileceğinizi gösterir:

* süreci aşamalara bölmek ve görevleri dinamik olarak eklemek;
* kullanıcı seçimlerine ve görev sonuçlarına tepki vermek;
* TUI'dan çıkmadan hatalardan toparlanmak.

<Info>
  Tüm kod parçaları `ziva` paketinin herkese açık API'sini kullanır. Bunları `examples` paketine koyabilir ve davranışı göstermek istediğinizde çağırabilirsiniz.
</Info>

## Çok aşamalı kurulum şablonu

```go theme={null}
// DeployCluster, kullanıcının yanıtlarını toplayan, ilerlemeyi gösteren
// ve sonraki adımlar için sonuçları saklayan sıralı bir kurulumu organize eder.
func DeployCluster() error {
    summary := ziva.NewFuncTask(
        "Ön kontroller",
        runPreflightChecks,
        ziva.WithSummaryFunction(func() []string {
            return []string{"DNS: ok", "Ağ: ok"}
        }),
        ziva.WithStopOnError(true),
    )

    topology := ziva.NewSingleSelectTask(
        "Topoloji",
        []string{
            "single-node::Tek düğüm",
            "multi-node::Çok düğüm",
            "ha::Yüksek erişilebilirlik",
        },
    ).WithDefaultItem("multi-node")

    nodes := ziva.NewInputTask(
        "Düğüm sayısı",
        "Kaç işçi düğümü kurulacak?",
    ).
        WithInputType(ziva.InputTypeNumber).
        WithValidator(ziva.DefaultValidators.Range(1, 20)).
        WithTimeout(30*time.Second, "3")

    queue := ziva.NewQueue("Ziva Dağıtımı").
        WithAppName("Ziva CLI").
        WithTasksNumbered(true, "[%02d]")

    queue.AddTasks(summary, topology, nodes)
    if err := queue.Run(); err != nil {
        return err
    }

    // Seçilen topolojiye göre ek görevler ekleyelim.
    followUp := ziva.NewQueue("Takip görevleri")

    switch topology.GetSelected() {
    case "single-node":
        followUp.AddTasks(planBackupTask(), confirmMetricsTask())
    case "multi-node":
        followUp.AddTasks(configureIngressTask(), scaleOutTask(nodes))
    case "ha":
        followUp.AddTasks(haPrecheckTask(), configureQuorumTask(nodes))
    }

    return followUp.Run()
}
```

### Öne çıkanlar

* **İki kuyruk çalıştırması.** İlk kuyruk girişleri toplar; ikinci kuyruk çalışma zamanında oluşturulur.
* **Özet fonksiyonu.** `WithSummaryFunction`, görevin altında kısa bir özet gösterir ve operatör geri bildirimini güçlendirir.
* **Zaman aşımı.** `WithTimeout`, başsız oturumların sonsuza kadar askıda kalmasını engeller.

## Kullanıcı onayıyla yeniden deneme

```go theme={null}
func RunWithRetries(label string, fn func() error, maxAttempts int) error {
    attempt := 1

    for {
        task := ziva.NewFuncTask(
            fmt.Sprintf("%s · deneme %d", label, attempt),
            fn,
            ziva.WithStopOnError(false),
        )

        queue := ziva.NewQueue(label)
        queue.AddTasks(task)

        if err := queue.Run(); err == nil {
            return nil
        }

        if attempt >= maxAttempts {
            return fmt.Errorf("deneme limiti aşıldı (%d)", maxAttempts)
        }

        retry := ziva.NewYesNoTask(
            "Tekrar dene",
            fmt.Sprintf("%d. deneme başarısız oldu. Tekrar denensin mi?", attempt),
        ).WithDefaultYesAndTimeout(10 * time.Second)

        confirmation := ziva.NewQueue("Tekrar kararı")
        confirmation.AddTasks(retry)
        confirmation.Run()

        if !retry.IsYes() {
            return fmt.Errorf("işlem %d. denemede iptal edildi", attempt)
        }

        attempt++
    }
}
```

### Ne zaman gerekli?

* kararsız altyapı çağrıları;
* güvenilir olmayan bağlantılarda ürün yazılımı güncellemeleri;
* insan onayıyla yeniden denenmesi gereken uzun işlemler.

## Görevleri uçuş sırasında oluşturma

```go theme={null}
func ConfigureServers() error {
    count := ziva.NewInputTask("Sunucu sayısı", "Kaç sunucu yapılandırılacak?").
        WithInputType(ziva.InputTypeNumber).
        WithValidator(ziva.DefaultValidators.Range(1, 8))

    baseQueue := ziva.NewQueue("Yapılandırma parametreleri")
    baseQueue.AddTasks(count)
    if err := baseQueue.Run(); err != nil {
        return err
    }

    n, _ := strconv.Atoi(count.GetValue())

    var tasks []ziva.Task
    for i := 1; i <= n; i++ {
        prefix := fmt.Sprintf("Sunucu %d", i)

        host := ziva.NewInputTask(prefix+" · host", "FQDN girin")
        host.WithValidator(ziva.DefaultValidators.Domain())

        port := ziva.NewInputTask(prefix+" · port", "Port girin")
        port.WithInputType(ziva.InputTypeNumber).
            WithValidator(ziva.DefaultValidators.Port())

        tasks = append(tasks, host, port)
    }

    servers := ziva.NewQueue("Sunucu yapılandırması").
        WithTasksNumbered(true, "[%02d]")
    servers.AddTasks(tasks...)
    return servers.Run()
}
```

<Note>
  Yüzlerce görev üretebilecek bir akışınız varsa yürütmeyi birkaç kuyruğa bölün ve bellek tüketimini tahmin edilebilir tutmak için bloklar halinde çalıştırın.
</Note>

## Karmaşık akışlar için hızlı kontrol listesi

* Sonuçlarına daha sonra ihtiyaç duyacağınız görevlerin referanslarını saklayın.
* Farklı aşamalar için ayrı kuyruklar kullanın — bu, mantığı ve test yazmayı kolaylaştırır.
* Ziva'un hedef sistemi otomatik ayarlaması için başlangıçta `AutoConfigure()` çağırın.
* Kısıtlı cihazlarda çıktıyı kompakt tutmak için `EnableEmbeddedMode()` ile `WithOutResultLine()` kombinasyonunu tercih edin.
* Kuyruk sırayla çalışır; sözde paralellik gerekiyorsa ek kuyrukları `FuncTask` içinden başlatın.

Dayanıklı formlar oluşturmayı öğrenmek için doğrulama demosuna göz atın.
