package main

import (
	"context"
	"errors"
	"fmt"
	"time"
)

// prosesLambat mensimulasikan pekerjaan berat selama 300 milidetik.
// Fungsi ini menghormati ctx: saat ctx melewati tenggat, prosesLambat
// kembali lebih cepat tanpa menunggu pekerjaan selesai.
func prosesLambat(ctx context.Context) (string, error) {
	selesai := make(chan string, 1)

	go func() {
		time.Sleep(300 * time.Millisecond) // simulasi pekerjaan berat
		selesai <- "data siap"
	}()

	select {
	case hasil := <-selesai:
		return hasil, nil
	case <-ctx.Done():
		return "", ctx.Err()
	}
}

func main() {
	// Tenggat 100 milidetik: pekerjaan 300 milidetik tidak akan selesai tepat waktu.
	ctxPendek, cancelPendek := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancelPendek()

	hasil, err := prosesLambat(ctxPendek)
	fmt.Printf("batas 100ms → hasil=%q err=%v\n", hasil, err)
	fmt.Println("DeadlineExceeded?", errors.Is(err, context.DeadlineExceeded))

	// Tenggat 500 milidetik: pekerjaan 300 milidetik selesai sebelum tenggat.
	ctxPanjang, cancelPanjang := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancelPanjang()

	hasil, err = prosesLambat(ctxPanjang)
	fmt.Printf("batas 500ms → hasil=%q err=%v\n", hasil, err)
}
