現在golangを勉強しており、特にgoroutine、context、cancel()、channelなどを色々試しています。

ふと、goroutineからgoroutineを起動してもよいのか?と思い、以下のようにmain()からgoroutineでparent()を実行し、さらにその中でgoroutineでchild()を実行するサンプルを作成してみました。
※child()を実行する条件は、pop()から取得できる値が1の場合のみとし、それ以外の場合は前のchild()を実行し続ける。次に1がきた場合は前のchild()を終了し新しいchild()を起動する…みたいなちょっと複雑な感じにしています。

package main

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

var (
    slices = []int{1, 2, 1, 2, 2, 2, 1, 2, 1}
)

func main() {
    fmt.Println("main start")

    ctx, cancel := context.WithCancel(context.Background())
    defer func() {
        cancel()
        time.Sleep(2 * time.Second)
    }()

    go parent(ctx)

    time.Sleep(4 * time.Second)

    fmt.Println("main end")
}

func parent(ctx context.Context) {
    fmt.Println("parent start")
    i := 0
    var childCtx context.Context
    var childCancel context.CancelFunc

    for {
        select {
        case <-ctx.Done():
            fmt.Println("parent cancel")
            return
        default:
            fmt.Println("parent process")
            i += 1
            v := pop()
            switch v {
            case 1:
                if childCancel != nil {
                    childCancel()
                }
                childCtx, childCancel = context.WithCancel(ctx)
                go child(childCtx, i)
            default:
                fmt.Printf("not start child: %d\r\n", i)
            }

            time.Sleep(1000 * time.Millisecond)
        }
    }
}

func child(ctx context.Context, i int) {
    fmt.Printf("child start: %d\r\n", i)

    for {
        select {
        case <-ctx.Done():
            fmt.Printf("child cancel: %d\r\n", i)
            return
        default:
            fmt.Printf("child process: %d\r\n", i)
            time.Sleep(100 * time.Millisecond)
        }
    }
}

func pop() int {
    var i int
    if len(slices) > 0 {
        i = slices[0]
        slices = slices[1:]
    }
    return i
}

ここで以下2点について質問させてください。

1.そもそもgoroutineからgoroutineを起動してもよいものなのでしょうか?
(documentを探しているのですが、見当たらなく…)

2.上記をPlaygroundで実行すると結果は出力されますが、go vet?により以下の警告がでます。

./prog.go:49:5: the childCancel function is not used on all paths (possible context leak)
./prog.go:39:4: this return statement may be reached without using the childCancel var defined on line 49

原因は記述のとおり「childCancel()が実行されないことがあるよ!」といったことだと思うのですが、これを回避する方法はございますでしょうか?

乱文で恐縮ですが、よろしくお願いいたします。