|
|
@@ -37,12 +37,12 @@ const (
|
|
|
|
|
|
// Create a new randomly generated board.
|
|
|
func New(width, height int) *Board {
|
|
|
- return NewPartial(0, 0, width, height, width, height)
|
|
|
+ return NewRegion(0, 0, width, height, width, height)
|
|
|
}
|
|
|
|
|
|
-func NewPartial(startX, startY, width, height, totalWidth, totalHeight int) *Board {
|
|
|
+func NewRegion(startX, startY, width, height, totalWidth, totalHeight int) *Board {
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano() + int64(startY+startY)))
|
|
|
- return newPartial(startX, startY, width, height, totalWidth, totalHeight, r)
|
|
|
+ return newRegion(startX, startY, width, height, totalWidth, totalHeight, r)
|
|
|
}
|
|
|
|
|
|
func NewRemote(width, height int) *Board {
|
|
|
@@ -52,20 +52,26 @@ func NewRemote(width, height int) *Board {
|
|
|
xRegions := (width + (regionWidth - 1)) / regionWidth
|
|
|
yRegions := (height + (regionHeight - 1)) / regionHeight
|
|
|
|
|
|
- returnChan := make(chan response, 32)
|
|
|
+ returnChan := make(chan *response, 32)
|
|
|
defer close(returnChan)
|
|
|
go b.genRegions(xRegions, yRegions, returnChan)
|
|
|
|
|
|
for answers := 0; xRegions*yRegions > answers; answers++ {
|
|
|
result := <-returnChan
|
|
|
log.Printf("Received partial: x=%v, y=%v, width=%v, height=%v\n", result.x, result.y, result.width, result.height)
|
|
|
+
|
|
|
+ if result.boardTile == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
for ry := 0; ry < result.height; ry++ {
|
|
|
i, _ := b.xyToIndex(result.x, result.y+ry)
|
|
|
- _, err := result.boardTile.Read(b.data[i : i+byteIndex(result.width)])
|
|
|
+ n, err := result.boardTile.Read(b.data[i : i+byteIndex(result.width)])
|
|
|
if !(err == nil || err == io.EOF) {
|
|
|
- log.Printf("ERROR: %v", err)
|
|
|
+ log.Printf("ERROR after reading %v bytes: %v\n", n, err)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
result.boardTile.Close()
|
|
|
}
|
|
|
|
|
|
@@ -90,10 +96,10 @@ type work struct {
|
|
|
height int
|
|
|
}
|
|
|
|
|
|
-func (b *Board) genRegions(xRegions, yRegions int, responseChan chan response) {
|
|
|
- const numWorkers = 50
|
|
|
+func (b *Board) genRegions(xRegions, yRegions int, responseChan chan *response) {
|
|
|
+ const numWorkers = 32
|
|
|
|
|
|
- workChan := make(chan work, numWorkers)
|
|
|
+ workChan := make(chan *work, numWorkers)
|
|
|
|
|
|
for i := 0; i < numWorkers; i++ {
|
|
|
go worker(workChan, responseChan)
|
|
|
@@ -103,13 +109,13 @@ func (b *Board) genRegions(xRegions, yRegions int, responseChan chan response) {
|
|
|
for j := 0; j < yRegions; j++ {
|
|
|
x := i * regionWidth
|
|
|
y := j * regionHeight
|
|
|
- workChan <- work{x, y, b.Width, b.Height}
|
|
|
+ workChan <- &work{x, y, b.Width, b.Height}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-func worker(workChan chan work, responseChan chan response) {
|
|
|
+func worker(workChan chan *work, responseChan chan *response) {
|
|
|
|
|
|
for w, open := <-workChan; open; w, open = <-workChan {
|
|
|
var partialWidth, partialHeight int
|
|
|
@@ -129,20 +135,27 @@ func worker(workChan chan work, responseChan chan response) {
|
|
|
log.Printf("Requested generation of tile with url: %v\n", requestUrl)
|
|
|
|
|
|
resp, err := http.Get(requestUrl)
|
|
|
- for err != nil {
|
|
|
- log.Printf("ERROR requesting region: %v", err)
|
|
|
+ const maxRetries = 3
|
|
|
+ for retries := 1; err != nil && retries < maxRetries; retries++ {
|
|
|
+ log.Printf("ERROR requesting region (try %v) : %v", retries, err)
|
|
|
+ time.Sleep(50 * time.Millisecond)
|
|
|
resp, err = http.Get(requestUrl)
|
|
|
}
|
|
|
|
|
|
- result := response{
|
|
|
+ var r io.ReadCloser
|
|
|
+ if err == nil {
|
|
|
+ r = resp.Body
|
|
|
+ } else {
|
|
|
+ log.Printf("ERROR requesting region, skipping (try %v) : %v", maxRetries, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ responseChan <- &response{
|
|
|
x: w.x,
|
|
|
y: w.y,
|
|
|
width: partialHeight,
|
|
|
height: partialHeight,
|
|
|
- boardTile: resp.Body,
|
|
|
+ boardTile: r,
|
|
|
}
|
|
|
-
|
|
|
- responseChan <- result
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -173,7 +186,7 @@ func (b *Board) WriteData(w io.Writer) {
|
|
|
n, err := w.Write(b.data)
|
|
|
|
|
|
if err != nil {
|
|
|
- fmt.Errorf("Error writing board after %v bytes: %v", n, err)
|
|
|
+ log.Printf("Error writing board after %v bytes: %v", n, err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -217,10 +230,10 @@ func newBlank(width, height int) *Board {
|
|
|
}
|
|
|
|
|
|
func new(width, height int, r *rand.Rand) *Board {
|
|
|
- return newPartial(0, 0, width, height, width, height, r)
|
|
|
+ return newRegion(0, 0, width, height, width, height, r)
|
|
|
}
|
|
|
|
|
|
-func newPartial(startX, startY, width, height, totalWidth, totalHeight int, r *rand.Rand) *Board {
|
|
|
+func newRegion(startX, startY, width, height, totalWidth, totalHeight int, r *rand.Rand) *Board {
|
|
|
b := newBlank(width, height)
|
|
|
leftLimit := (totalWidth-maxIceWidth)/2 - startX
|
|
|
rightLimit := totalWidth/2 + maxIceWidth/2 - startX
|