Webcrawler en Go

Estoy tratando de construir un rastreador web en Go donde me gustaría especificar el número máximo de trabajadores concurrentes. Todos trabajarán siempre que haya un enlace para explorar en la cola. Cuando la cola tiene menos elementos que los trabajadores, los trabajadores deben gritar, pero reanudar en caso de que se encuentren más enlaces.

El código que probé es

const max_workers = 6
// simulating links with int
func crawl(wg *sync.WaitGroup, queue chan int) {
    for element := range queue {   
        wg.Done() // why is defer here causing a deadlock?
        fmt.Println("adding 2 new elements ")
        if element%2 == 0 {
            wg.Add(2)
            queue <- (element*100 + 11)
            queue <- (element*100 + 33)
        }

    }
}

func main() {
    var wg sync.WaitGroup
    queue := make(chan int, 10)
    queue <- 0
    queue <- 1
    queue <- 2
    queue <- 3
    var min int
    if (len(queue) < max_workers) {
        min = len(queue)
    } else {
        min = max_workers
    }
    for i := 0; i < min; i++ {
        wg.Add(1)
        go crawl(&wg, queue)
    }
    wg.Wait()
    close(queue)
}

Enlace al patio de recreo

Esto parece funcionar, pero hay un problema: tengo que llenar la cola con más de un elemento cuando comienzo. Me gustaría que comenzara desde una página de inicio (única) (en mi ejemploqueue <- 0) y luego aumentar / reducir el grupo de trabajo de forma dinámica.

Mis preguntas son:

¿Cómo puedo obtener comportamiento?

por qué es diferirwg.Done() causando un punto muerto? Es normalwg.Done() la función cuando realmente se completa? Creo que sin eldefer la rutina no está esperando a que termine la otra parte (lo que podría llevar más tiempo en el ejemplo de trabajo real de analizar HTML).

Respuestas a la pregunta(1)

Su respuesta a la pregunta