Filter queue in a single goroutine for accuracy

Filtering in the enqueue function is less reliable because the function
adds the item in a goroutine, so there's no guarantee that all the
pending adds are completed at the time of filtering.

For a demonstration, try running the crawler on https://apple.com/ and
you should see a fair number of duplicate URLs get fetched.

This modification uses channels for synchronization. It has the benefit
of cleaning up the design by keeping each routine simple and only
concerned with one thing, and eliminating a weird bit of shared memory.