package main

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

type requestIDKey struct{}

func WithRequestID(ctx context.Context, id string) context.Context {
	return context.WithValue(ctx, requestIDKey{}, id)
}
func RequestID(ctx context.Context) (string, bool) {
	id, ok := ctx.Value(requestIDKey{}).(string)
	return id, ok
}
func WaitForStop(ctx context.Context) error {
	<-ctx.Done()
	return ctx.Err()
}
func Send(ctx context.Context, result chan<- int, value int) error {
	select {
	case result <- value:
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}
func main() {
	parent, cancel := context.WithCancelCause(context.Background())
	child, childCancel := context.WithCancel(WithRequestID(parent, "req-7"))
	defer childCancel()
	result := make(chan error, 1)
	go func() { result <- WaitForStop(child) }()
	cancel(errors.New("client left"))
	fmt.Println(<-result)
	fmt.Println(context.Cause(child))
	id, _ := RequestID(child)
	fmt.Println(id)
	expired, stop := context.WithTimeout(context.Background(), 0)
	defer stop()
	fmt.Println(WaitForStop(expired))
	p, pc := context.WithDeadline(context.Background(), time.Now().Add(time.Hour))
	defer pc()
	c, cc := context.WithTimeout(p, 2*time.Hour)
	pd, _ := p.Deadline()
	cd, _ := c.Deadline()
	fmt.Println("earlier deadline:", pd.Equal(cd))
	cc()
	fmt.Println("child stopped; parent active:", c.Err() != nil, p.Err() == nil)
}
