mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-17 23:58:17 +01:00
mtwebmapper: To avoid possible races when serving tiles the same time as re-generating them the re-generation write them to temp files and rename them afterwards.
This commit is contained in:
parent
e899b13889
commit
3e4c1aa2d9
@ -10,7 +10,9 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"bitbucket.org/s_l_teichmann/mtredisalize/common"
|
"bitbucket.org/s_l_teichmann/mtredisalize/common"
|
||||||
@ -107,7 +109,7 @@ func (tu *tileUpdater) doUpdates() (err error) {
|
|||||||
if client, err = common.NewRedisClient("tcp", tu.redisAddress); err != nil {
|
if client, err = common.NewRedisClient("tcp", tu.redisAddress); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
btc := NewBaseTileCreator(client, tu.colors, baseDir)
|
btc := NewBaseTileCreator(client, tu.colors, baseDir, true)
|
||||||
go btc.run(jobs)
|
go btc.run(jobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,17 +139,22 @@ type BaseTileCreator struct {
|
|||||||
renderer *common.Renderer
|
renderer *common.Renderer
|
||||||
yOrder *common.YOrder
|
yOrder *common.YOrder
|
||||||
baseDir string
|
baseDir string
|
||||||
|
update bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBaseTileCreator(client *common.RedisClient,
|
func NewBaseTileCreator(
|
||||||
colors *common.Colors, baseDir string) *BaseTileCreator {
|
client *common.RedisClient,
|
||||||
|
colors *common.Colors,
|
||||||
|
baseDir string,
|
||||||
|
update bool) *BaseTileCreator {
|
||||||
renderer := common.NewRenderer(tileWidth, tileHeight)
|
renderer := common.NewRenderer(tileWidth, tileHeight)
|
||||||
return &BaseTileCreator{
|
return &BaseTileCreator{
|
||||||
client: client,
|
client: client,
|
||||||
colors: colors,
|
colors: colors,
|
||||||
baseDir: baseDir,
|
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
yOrder: common.NewYOrder(renderer, yOrderCapacity)}
|
yOrder: common.NewYOrder(renderer, yOrderCapacity),
|
||||||
|
baseDir: baseDir,
|
||||||
|
update: update}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (btc *BaseTileCreator) run(jobs chan xz) {
|
func (btc *BaseTileCreator) run(jobs chan xz) {
|
||||||
@ -215,10 +222,25 @@ func (btc *BaseTileCreator) createTile(x, z int16, i, j int) error {
|
|||||||
16, 16, (tileWidth-2)*16, (tileHeight-2)*16,
|
16, 16, (tileWidth-2)*16, (tileHeight-2)*16,
|
||||||
btc.colors.Colors, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff})
|
btc.colors.Colors, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff})
|
||||||
|
|
||||||
path := filepath.Join(btc.baseDir, fmt.Sprintf("%d", i), fmt.Sprintf("%d.png", j))
|
path := filepath.Join(btc.baseDir, strconv.Itoa(i), fmt.Sprintf("%d.png", j))
|
||||||
log.Printf("file path: %s", path)
|
|
||||||
|
|
||||||
log.Printf("Writing (%d, %d) (%d, %d)", i, j, x, z)
|
log.Printf("Writing (%d, %d) to file %s", x, z, path)
|
||||||
|
|
||||||
return common.SaveAsPNG(path, image)
|
if !btc.update {
|
||||||
|
return common.SaveAsPNG(path, image)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to make creation of update "atomic" by first writing to tmp file
|
||||||
|
// and rename the tmp file to the original one afterwards.
|
||||||
|
pathTmp := path + "tmp"
|
||||||
|
pathTmpPre := pathTmp
|
||||||
|
tc := 0
|
||||||
|
for _, err := os.Stat(pathTmp); err == nil; _, err = os.Stat(pathTmp) {
|
||||||
|
pathTmp = fmt.Sprintf("%s%d", pathTmpPre, tc)
|
||||||
|
tc++
|
||||||
|
}
|
||||||
|
if err := common.SaveAsPNG(pathTmp, image); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.Rename(pathTmp, path)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user