You have your Site, which is the data for a particular site:
type Site struct {
url string
data map[int64]string // for example
}
func NewSite(url string) *Site {
// set up and return a pointer to a new Site
}
Then you might think about what kind of work you want to be doing, and
define that work as a struct.
type Work struct {
site *Site
err os.Error
}
Then you create a Poll function (of which you can run many in seprate
goroutines) that read form a channel of Work, and send the updated
Work to an output channel:
func Poll(in <-chan Work, out chan<- Work) {
for w := range in {
// do some work, update w
out <- w
}
}
Then in your main function, you set up those channels, launch a bunch
of Poll workers, create some Sites, and handle the distribution of
work:
var urls = []string {
"http://example.com/",
"http://example.net/",
"http://example.org/",
}
const numWorkers = 10
func main() {
// create channels
pending, complete := make(chan Work), make(chan Work)
// launch workers
for i := 0; i < numWorkers; i++ {
go Poll(pending, complete)
}
// create some initial work
go func() {
for _, url := range urls {
s := NewSite(url)
pending <- Work{s, nil}
}
}()
// process completed work
for w := range complete {
if w.err != nil {
// handle error
}
// process completed work somehow
// now put the site back into the pending queue for re-processing
// (or don't, if you don't want to process it again)
go func(s *Site) {
// we do this in a goroutine
// because the send will block until a worker is ready
// we could also put a time.Sleep here
// if you want to wait before re-processing the site
pending <- Work{s, nil}
}(w.site)
}
}
Now I haven't run or tested this code at all, and there may be
refinements or further simplifications to the process that can be
made, but I hope this gives you the general idea of what we mean by
"share memory by communicating".
Please let me know if you have any questions! :-)
Andrew
Andrew