Skip to content
This repository was archived by the owner on Apr 7, 2019. It is now read-only.

Commit

Permalink
default to file based tile cache
Browse files Browse the repository at this point in the history
  • Loading branch information
naturefreshmilk committed Jul 6, 2018
1 parent a3a8a5e commit 0b5357d
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 203 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ logs
node_modules
heimdallr-data
.idea
*.iml
*.iml
tiles
79 changes: 33 additions & 46 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,43 +36,10 @@ Please create an issue with minetest-version and MapBlock info in the bug-tracke
# Installing

* Download the jar in the releases section
* Set up a tileserver database (empty, `create database tiles;`)
* **Backup** your minetest database (**THIS IS IMPORTANT!!**) as the db schema gets updated (see **How it works**)
* Configure the database connections according to the **Configuration** section if they are not default value
* Configure the database connection according to the **Configuration** section if they are not default value
* Start the server with: `java -jar tileserver.jar`

# How it works

The **blocks** table in the minetest database gets a new column for the modification time.
Triggers for `insert` and `update` on the table ensure the time gets updated after each change:

```sql
alter table blocks add column mtime bigint not null default 0;
create index BLOCKS_TIME on blocks(mtime);

create or replace function on_blocks_change() returns trigger as
$BODY$
BEGIN
NEW.mtime = floor(EXTRACT(EPOCH from now()) * 1000);
return NEW;
END;
$BODY$
LANGUAGE plpgsql;

create trigger blocks_update
before insert or update
on blocks
for each row
execute procedure on_blocks_change();

```
**These changes get applied atomatically with the initial DB-Migration, so please create a backup before starting the Tileserver!!**

With this information and the modification-time on the created tiles the
periodically scheduled Updater-Job removes the stale Tiles in the tile-cache.

On the next access (browsing on the web-interface to the coordinates) the Tile gets re-rendered.

# Configuring

The application drwas its configuration from the `tileserver.properties` file.
Expand Down Expand Up @@ -124,21 +91,41 @@ Username for DB Connection
Driver for DB Connection (only psql supported for now)
* Default: **org.postgresql.Driver**

### tile.db.url
Url for Tile-DB Connection (jdbc connection string)
* Default: **jdbc:postgresql://127.0.0.1:5432/tiles**

### tile.db.username
Username for Tile-DB Connection
* Default: **sa**

### tile.db.password
Username for Tile-DB Connection
* Default:

### tile.db.driver
Driver for Tile-DB Connection (only psql supported for now)
* Default: **org.postgresql.Driver**
# How it works

The **blocks** table in the minetest database gets a new column for the modification time.
Triggers for `insert` and `update` on the table ensure the time gets updated after each change:

```sql
alter table blocks add column mtime bigint not null default 0;
create index BLOCKS_TIME on blocks(mtime);

create or replace function on_blocks_change() returns trigger as
$BODY$
BEGIN
NEW.mtime = floor(EXTRACT(EPOCH from now()) * 1000);
return NEW;
END;
$BODY$
LANGUAGE plpgsql;

create trigger blocks_update
before insert or update
on blocks
for each row
execute procedure on_blocks_change();

```
**These changes get applied atomatically with the initial DB-Migration, so please create a backup before starting the Tileserver!!**

With this information and the modification-time on the created tiles the
periodically scheduled Updater-Job removes the stale Tiles in the tile-cache.

On the next access (browsing on the web-interface to the coordinates) the Tile gets re-rendered.


# Building

Expand Down
14 changes: 9 additions & 5 deletions src/main/java/io/rudin/minetest/tileserver/DBMigration.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ public DBMigration(TileServerConfig cfg) {
flyway.setBaselineVersionAsString("0");
flyway.setBaselineOnMigrate(true);

this.tileFlyway = new Flyway();
tileFlyway.setDataSource(cfg.tileDatabaseUrl(), cfg.tileDatabaseUsername(), cfg.tileDatabasePassword());
tileFlyway.setSqlMigrationPrefix("TILEV");
if (cfg.tileCacheType() == TileServerConfig.CacheType.DATABASE) {
this.tileFlyway = new Flyway();
tileFlyway.setDataSource(cfg.tileDatabaseUrl(), cfg.tileDatabaseUsername(), cfg.tileDatabasePassword());
tileFlyway.setSqlMigrationPrefix("TILEV");
}
}

private final Flyway flyway;
private final Flyway tileFlyway;
private Flyway tileFlyway;

public void migrate() {
tileFlyway.migrate();
if (tileFlyway != null)
tileFlyway.migrate();

flyway.migrate();
}

Expand Down
10 changes: 6 additions & 4 deletions src/main/java/io/rudin/minetest/tileserver/StaticTileGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;

import io.rudin.minetest.tileserver.config.TileServerConfig;
import org.aeonbits.owner.ConfigFactory;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record2;
Expand All @@ -22,15 +23,16 @@ public class StaticTileGen {
public static void main(String[] args) throws Exception {
// TODO create tiles in directory with static html index file

TileServerConfig cfg = ConfigFactory.create(TileServerConfig.class);

Injector injector = Guice.createInjector(
new ConfigModule(),
new DBModule(),
new ServiceModule()
new ConfigModule(cfg),
new DBModule(cfg),
new ServiceModule(cfg)
);

DSLContext ctx = injector.getInstance(DSLContext.class);
TileRenderer tileRenderer = injector.getInstance(TileRenderer.class);
TileServerConfig cfg = injector.getInstance(TileServerConfig.class);

Condition yCondition = BLOCKS.POSY.between(cfg.tilesMinY(), cfg.tilesMaxY());

Expand Down
15 changes: 9 additions & 6 deletions src/main/java/io/rudin/minetest/tileserver/TileServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,23 @@
import io.rudin.minetest.tileserver.transformer.JsonTransformer;
import io.rudin.minetest.tileserver.ws.WebSocketHandler;
import io.rudin.minetest.tileserver.ws.WebSocketUpdater;
import org.aeonbits.owner.ConfigFactory;

import static spark.Spark.*;

public class TileServer {

private static Injector injector = Guice.createInjector(
new ConfigModule(),
new DBModule(),
new ServiceModule()
);

public static void main(String[] args) throws Exception {

TileServerConfig cfg = injector.getInstance(TileServerConfig.class);
TileServerConfig cfg = ConfigFactory.create(TileServerConfig.class);


Injector injector = Guice.createInjector(
new ConfigModule(cfg),
new DBModule(cfg),
new ServiceModule(cfg)
);

DBMigration dbMigration = injector.getInstance(DBMigration.class);
dbMigration.migrate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,21 @@ public interface TileServerConfig extends Config {
@DefaultValue("true")
boolean poiEnable();

/*
tile cache stuff
*/

@Key("tile.cache.impl")
@DefaultValue("FILE")
CacheType tileCacheType();

enum CacheType {
DATABASE,
FILE
}

@Key("tiles.directory")
@DefaultValue("target/tiles")
@Deprecated
@DefaultValue("tiles")
String tileDirectory();

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ public class UpdateChangedTilesJob implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(UpdateChangedTilesJob.class);

@Inject
public UpdateChangedTilesJob(DSLContext ctx, @TileDB DSLContext tileCtx, TileCache tileCache, EventBus eventBus, TileServerConfig cfg) {
public UpdateChangedTilesJob(DSLContext ctx, TileCache tileCache, EventBus eventBus, TileServerConfig cfg) {
this.ctx = ctx;
this.tileCtx = tileCtx;
this.tileCache = tileCache;
this.eventBus = eventBus;

Expand All @@ -44,7 +43,7 @@ public UpdateChangedTilesJob(DSLContext ctx, @TileDB DSLContext tileCtx, TileCac

private final EventBus eventBus;

private final DSLContext ctx, tileCtx;
private final DSLContext ctx;

private final TileCache tileCache;

Expand All @@ -67,13 +66,10 @@ public void run() {
}

if (latestTimestamp == null) {
logger.debug("Gathering latest tile time from db");
logger.debug("Gathering latest tile time from tile cache");
long start = System.currentTimeMillis();

latestTimestamp = tileCtx
.select(DSL.max(TILES.MTIME))
.from(TILES)
.fetchOne(DSL.max(TILES.MTIME));
latestTimestamp = tileCache.getLatestTimestamp();

long diff = System.currentTimeMillis() - start;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@

public class ConfigModule extends AbstractModule {

public ConfigModule(TileServerConfig cfg){
this.cfg = cfg;
}

private final TileServerConfig cfg;

@Override
protected void configure() {
bind(TileServerConfig.class).toInstance(ConfigFactory.create(TileServerConfig.class));
bind(TileServerConfig.class).toInstance(cfg);
}

}
16 changes: 13 additions & 3 deletions src/main/java/io/rudin/minetest/tileserver/module/DBModule.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.rudin.minetest.tileserver.module;

import com.google.inject.Key;
import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.qualifier.TileDB;
import io.rudin.minetest.tileserver.provider.*;
import org.jooq.DSLContext;
Expand All @@ -11,15 +12,24 @@

public class DBModule extends AbstractModule {

public DBModule(TileServerConfig cfg) throws Exception {
this.cfg = cfg;
}

private final TileServerConfig cfg;


@Override
protected void configure() {
bind(HikariConfig.class).toProvider(HikariConfigProvider.class);
bind(HikariDataSource.class).toProvider(HikariDatasourceProvider.class);
bind(DSLContext.class).toProvider(DSLContextProvider.class);

bind(Key.get(HikariConfig.class, TileDB.class)).toProvider(TileDBHikariConfigProvider.class);
bind(Key.get(HikariDataSource.class, TileDB.class)).toProvider(TileDBHikariDatasourceProvider.class);
bind(Key.get(DSLContext.class, TileDB.class)).toProvider(TileDBDSLContextProvider.class);
if (cfg.tileCacheType() == TileServerConfig.CacheType.DATABASE) {
bind(Key.get(HikariConfig.class, TileDB.class)).toProvider(TileDBHikariConfigProvider.class);
bind(Key.get(HikariDataSource.class, TileDB.class)).toProvider(TileDBHikariDatasourceProvider.class);
bind(Key.get(DSLContext.class, TileDB.class)).toProvider(TileDBDSLContextProvider.class);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
import com.google.inject.AbstractModule;

import io.rudin.minetest.tileserver.ColorTable;
import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.provider.ColorTableProvider;
import io.rudin.minetest.tileserver.provider.ExecutorProvider;
import io.rudin.minetest.tileserver.service.EventBus;
import io.rudin.minetest.tileserver.service.TileCache;
import io.rudin.minetest.tileserver.service.impl.DatabaseTileCache;
import io.rudin.minetest.tileserver.service.impl.EventBusImpl;
import io.rudin.minetest.tileserver.service.impl.FileTileCache;
import org.jooq.util.jaxb.Database;

public class ServiceModule extends AbstractModule {

public ServiceModule(){
this(DatabaseTileCache.class);
public ServiceModule(TileServerConfig cfg) throws Exception {
this.cfg = cfg;
}

public ServiceModule(Class<? extends TileCache> cacheImpl){
this.cacheImpl = cacheImpl;
}

private final Class<? extends TileCache> cacheImpl;
private final TileServerConfig cfg;

@Override
protected void configure() {
bind(TileCache.class).to(cacheImpl);


if (cfg.tileCacheType() == TileServerConfig.CacheType.DATABASE)
bind(TileCache.class).to(DatabaseTileCache.class);
else
bind(TileCache.class).to(FileTileCache.class);

//bind(TileCache.class).to(FileTileCache.class);
bind(EventBus.class).to(EventBusImpl.class);
bind(ColorTable.class).toProvider(ColorTableProvider.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ public interface TileCache {
boolean has(int x, int y, int z);

void remove(int x, int y, int z);


long getLatestTimestamp();

}
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,26 @@ public void remove(int x, int y, int z) {
String key = getKey(x, y, z);
cache.invalidate(key);

long start = System.currentTimeMillis();

ctx.delete(TILES)
.where(TILES.X.eq(x))
.and(TILES.Y.eq(y))
.and(TILES.Z.eq(z))
.execute();

long diff = System.currentTimeMillis() - start;
if (diff > 500){
logger.warn("Tile removal ({},{},{}) took {} ms", x,y,z, diff);
}
}

@Override
public long getLatestTimestamp() {
return ctx
.select(DSL.max(TILES.MTIME))
.from(TILES)
.fetchOne(DSL.max(TILES.MTIME));
}

@Override
Expand Down
Loading

0 comments on commit 0b5357d

Please sign in to comment.