mirror of
https://github.com/maplibre/martin.git
synced 2024-12-19 04:41:46 +03:00
parent
66a850e215
commit
5eeef48b30
20
README.md
20
README.md
@ -85,6 +85,8 @@ Table Sources list endpoint is available at `/index.json`
|
|||||||
curl localhost:3000/index.json
|
curl localhost:3000/index.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note**: if in `watch` mode, this will rescan database for table sources.
|
||||||
|
|
||||||
### Table Source TileJSON
|
### Table Source TileJSON
|
||||||
|
|
||||||
Table Source [TileJSON](https://github.com/mapbox/tilejson-spec) endpoint is available at `/{schema_name}.{table_name}.json`.
|
Table Source [TileJSON](https://github.com/mapbox/tilejson-spec) endpoint is available at `/{schema_name}.{table_name}.json`.
|
||||||
@ -146,6 +148,8 @@ Function Sources list endpoint is available at `/rpc/index.json`
|
|||||||
curl localhost:3000/rpc/index.json
|
curl localhost:3000/rpc/index.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note**: if in `watch` mode, this will rescan database for function sources.
|
||||||
|
|
||||||
### Function Source TileJSON
|
### Function Source TileJSON
|
||||||
|
|
||||||
Function Source [TileJSON](https://github.com/mapbox/tilejson-spec) endpoint is available at `/rpc/{schema_name}.{function_name}.json`
|
Function Source [TileJSON](https://github.com/mapbox/tilejson-spec) endpoint is available at `/rpc/{schema_name}.{function_name}.json`
|
||||||
@ -179,11 +183,12 @@ Usage:
|
|||||||
Options:
|
Options:
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
-v --version Show version.
|
-v --version Show version.
|
||||||
--workers=<n> Number of web server workers.
|
--config=<path> Path to config file.
|
||||||
--pool_size=<n> Maximum connections pool size [default: 20].
|
|
||||||
--keep_alive=<n> Connection keep alive timeout [default: 75].
|
--keep_alive=<n> Connection keep alive timeout [default: 75].
|
||||||
--listen_addresses=<n> The socket address to bind [default: 0.0.0.0:3000].
|
--listen_addresses=<n> The socket address to bind [default: 0.0.0.0:3000].
|
||||||
--config=<path> Path to config file.
|
--pool_size=<n> Maximum connections pool size [default: 20].
|
||||||
|
--watch Scan for new sources on sources list requests
|
||||||
|
--workers=<n> Number of web server workers.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
@ -194,8 +199,9 @@ You can also configure martin using environment variables
|
|||||||
| -------------------- | -------------------------------- | ----------------------------- |
|
| -------------------- | -------------------------------- | ----------------------------- |
|
||||||
| DATABASE_URL | postgres://postgres@localhost/db | postgres database connection |
|
| DATABASE_URL | postgres://postgres@localhost/db | postgres database connection |
|
||||||
| DATABASE_POOL_SIZE | 20 | maximum connections pool size |
|
| DATABASE_POOL_SIZE | 20 | maximum connections pool size |
|
||||||
| WORKER_PROCESSES | 8 | number of web server workers |
|
|
||||||
| KEEP_ALIVE | 75 | connection keep alive timeout |
|
| KEEP_ALIVE | 75 | connection keep alive timeout |
|
||||||
|
| WATCH_MODE | true | scan for new sources |
|
||||||
|
| WORKER_PROCESSES | 8 | number of web server workers |
|
||||||
|
|
||||||
## Configuration File
|
## Configuration File
|
||||||
|
|
||||||
@ -208,6 +214,9 @@ martin --config config.yaml
|
|||||||
You can find an example of a configuration file [here](https://github.com/urbica/martin/blob/master/tests/config.yaml).
|
You can find an example of a configuration file [here](https://github.com/urbica/martin/blob/master/tests/config.yaml).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# Database connection string
|
||||||
|
connection_string: 'postgres://postgres@localhost/db'
|
||||||
|
|
||||||
# Maximum connections pool size [default: 20]
|
# Maximum connections pool size [default: 20]
|
||||||
pool_size: 20
|
pool_size: 20
|
||||||
|
|
||||||
@ -220,6 +229,9 @@ worker_processes: 8
|
|||||||
# The socket address to bind [default: 0.0.0.0:3000]
|
# The socket address to bind [default: 0.0.0.0:3000]
|
||||||
listen_addresses: '0.0.0.0:3000'
|
listen_addresses: '0.0.0.0:3000'
|
||||||
|
|
||||||
|
# Enable watch mode
|
||||||
|
watch: true
|
||||||
|
|
||||||
# associative arrays of table sources
|
# associative arrays of table sources
|
||||||
table_sources:
|
table_sources:
|
||||||
public.table_source:
|
public.table_source:
|
||||||
|
43
src/app.rs
43
src/app.rs
@ -1,6 +1,6 @@
|
|||||||
use actix::*;
|
use actix::*;
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
use futures::future::Future;
|
use futures::future::{result, Future};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -20,14 +20,16 @@ pub struct State {
|
|||||||
coordinator: Addr<CoordinatorActor>,
|
coordinator: Addr<CoordinatorActor>,
|
||||||
table_sources: Rc<RefCell<Option<TableSources>>>,
|
table_sources: Rc<RefCell<Option<TableSources>>>,
|
||||||
function_sources: Rc<RefCell<Option<FunctionSources>>>,
|
function_sources: Rc<RefCell<Option<FunctionSources>>>,
|
||||||
|
watch_mode: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_table_sources(
|
fn get_table_sources(
|
||||||
req: &HttpRequest<State>,
|
req: &HttpRequest<State>,
|
||||||
) -> Result<Box<Future<Item = HttpResponse, Error = Error>>> {
|
) -> Result<Box<Future<Item = HttpResponse, Error = Error>>> {
|
||||||
let state = &req.state();
|
let state = &req.state();
|
||||||
|
if state.watch_mode {
|
||||||
|
info!("Scanning database for table sources");
|
||||||
let coordinator = state.coordinator.clone();
|
let coordinator = state.coordinator.clone();
|
||||||
|
|
||||||
let result = req.state().db.send(messages::GetTableSources {});
|
let result = req.state().db.send(messages::GetTableSources {});
|
||||||
|
|
||||||
let response = result
|
let response = result
|
||||||
@ -46,7 +48,21 @@ fn get_table_sources(
|
|||||||
})
|
})
|
||||||
.responder();
|
.responder();
|
||||||
|
|
||||||
Ok(response)
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
let table_sources = state
|
||||||
|
.table_sources
|
||||||
|
.borrow()
|
||||||
|
.clone()
|
||||||
|
.ok_or_else(|| error::ErrorNotFound("There is no table sources"))?;
|
||||||
|
|
||||||
|
let http_response = HttpResponse::Ok()
|
||||||
|
.header("Access-Control-Allow-Origin", "*")
|
||||||
|
.json(table_sources);
|
||||||
|
|
||||||
|
let response = result(Ok(http_response)).responder();
|
||||||
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_table_source(req: &HttpRequest<State>) -> Result<HttpResponse> {
|
fn get_table_source(req: &HttpRequest<State>) -> Result<HttpResponse> {
|
||||||
@ -138,6 +154,8 @@ fn get_function_sources(
|
|||||||
req: &HttpRequest<State>,
|
req: &HttpRequest<State>,
|
||||||
) -> Result<Box<Future<Item = HttpResponse, Error = Error>>> {
|
) -> Result<Box<Future<Item = HttpResponse, Error = Error>>> {
|
||||||
let state = &req.state();
|
let state = &req.state();
|
||||||
|
if state.watch_mode {
|
||||||
|
info!("Scanning database for function sources");
|
||||||
let coordinator = state.coordinator.clone();
|
let coordinator = state.coordinator.clone();
|
||||||
|
|
||||||
let result = req.state().db.send(messages::GetFunctionSources {});
|
let result = req.state().db.send(messages::GetFunctionSources {});
|
||||||
@ -157,7 +175,21 @@ fn get_function_sources(
|
|||||||
})
|
})
|
||||||
.responder();
|
.responder();
|
||||||
|
|
||||||
Ok(response)
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_sources = state
|
||||||
|
.function_sources
|
||||||
|
.borrow()
|
||||||
|
.clone()
|
||||||
|
.ok_or_else(|| error::ErrorNotFound("There is no table sources"))?;
|
||||||
|
|
||||||
|
let http_response = HttpResponse::Ok()
|
||||||
|
.header("Access-Control-Allow-Origin", "*")
|
||||||
|
.json(function_sources);
|
||||||
|
|
||||||
|
let response = result(Ok(http_response)).responder();
|
||||||
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_function_source(req: &HttpRequest<State>) -> Result<HttpResponse> {
|
fn get_function_source(req: &HttpRequest<State>) -> Result<HttpResponse> {
|
||||||
@ -248,6 +280,7 @@ pub fn new(
|
|||||||
coordinator: Addr<CoordinatorActor>,
|
coordinator: Addr<CoordinatorActor>,
|
||||||
table_sources: Option<TableSources>,
|
table_sources: Option<TableSources>,
|
||||||
function_sources: Option<FunctionSources>,
|
function_sources: Option<FunctionSources>,
|
||||||
|
watch_mode: bool,
|
||||||
) -> App<State> {
|
) -> App<State> {
|
||||||
let table_sources_rc = Rc::new(RefCell::new(table_sources));
|
let table_sources_rc = Rc::new(RefCell::new(table_sources));
|
||||||
let function_sources_rc = Rc::new(RefCell::new(function_sources));
|
let function_sources_rc = Rc::new(RefCell::new(function_sources));
|
||||||
@ -265,6 +298,7 @@ pub fn new(
|
|||||||
coordinator,
|
coordinator,
|
||||||
table_sources: table_sources_rc.clone(),
|
table_sources: table_sources_rc.clone(),
|
||||||
function_sources: function_sources_rc.clone(),
|
function_sources: function_sources_rc.clone(),
|
||||||
|
watch_mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
App::with_state(state)
|
App::with_state(state)
|
||||||
@ -328,6 +362,7 @@ mod tests {
|
|||||||
State {
|
State {
|
||||||
db,
|
db,
|
||||||
coordinator,
|
coordinator,
|
||||||
|
watch_mode: true,
|
||||||
table_sources: table_sources_rc.clone(),
|
table_sources: table_sources_rc.clone(),
|
||||||
function_sources: function_sources_rc.clone(),
|
function_sources: function_sources_rc.clone(),
|
||||||
}
|
}
|
||||||
|
18
src/cli.rs
18
src/cli.rs
@ -9,21 +9,23 @@ Usage:
|
|||||||
Options:
|
Options:
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
-v --version Show version.
|
-v --version Show version.
|
||||||
--workers=<n> Number of web server workers.
|
--config=<path> Path to config file.
|
||||||
--pool_size=<n> Maximum connections pool size [default: 20].
|
|
||||||
--keep_alive=<n> Connection keep alive timeout [default: 75].
|
--keep_alive=<n> Connection keep alive timeout [default: 75].
|
||||||
--listen_addresses=<n> The socket address to bind [default: 0.0.0.0:3000].
|
--listen_addresses=<n> The socket address to bind [default: 0.0.0.0:3000].
|
||||||
--config=<path> Path to config file.
|
--pool_size=<n> Maximum connections pool size [default: 20].
|
||||||
|
--watch Scan for new sources on sources list requests
|
||||||
|
--workers=<n> Number of web server workers.
|
||||||
";
|
";
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
|
pub arg_connection: Option<String>,
|
||||||
|
pub flag_config: Option<String>,
|
||||||
pub flag_help: bool,
|
pub flag_help: bool,
|
||||||
pub flag_version: bool,
|
|
||||||
pub flag_workers: Option<usize>,
|
|
||||||
pub flag_pool_size: Option<u32>,
|
|
||||||
pub flag_keep_alive: Option<usize>,
|
pub flag_keep_alive: Option<usize>,
|
||||||
pub flag_listen_addresses: Option<String>,
|
pub flag_listen_addresses: Option<String>,
|
||||||
pub flag_config: Option<String>,
|
pub flag_pool_size: Option<u32>,
|
||||||
pub arg_connection: Option<String>,
|
pub flag_watch: bool,
|
||||||
|
pub flag_version: bool,
|
||||||
|
pub flag_workers: Option<usize>,
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use super::table_source::{get_table_sources, TableSources};
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
pub watch: bool,
|
||||||
pub pool_size: u32,
|
pub pool_size: u32,
|
||||||
pub keep_alive: usize,
|
pub keep_alive: usize,
|
||||||
pub worker_processes: usize,
|
pub worker_processes: usize,
|
||||||
@ -23,6 +24,7 @@ pub struct Config {
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ConfigBuilder {
|
struct ConfigBuilder {
|
||||||
|
pub watch: Option<bool>,
|
||||||
pub pool_size: Option<u32>,
|
pub pool_size: Option<u32>,
|
||||||
pub keep_alive: Option<usize>,
|
pub keep_alive: Option<usize>,
|
||||||
pub worker_processes: Option<usize>,
|
pub worker_processes: Option<usize>,
|
||||||
@ -35,6 +37,7 @@ struct ConfigBuilder {
|
|||||||
impl ConfigBuilder {
|
impl ConfigBuilder {
|
||||||
pub fn finalize(self) -> Config {
|
pub fn finalize(self) -> Config {
|
||||||
Config {
|
Config {
|
||||||
|
watch: self.watch.unwrap_or(false),
|
||||||
pool_size: self.pool_size.unwrap_or(20),
|
pool_size: self.pool_size.unwrap_or(20),
|
||||||
keep_alive: self.keep_alive.unwrap_or(75),
|
keep_alive: self.keep_alive.unwrap_or(75),
|
||||||
worker_processes: self.worker_processes.unwrap_or_else(num_cpus::get),
|
worker_processes: self.worker_processes.unwrap_or_else(num_cpus::get),
|
||||||
@ -59,16 +62,6 @@ pub fn read_config(file_name: &str) -> io::Result<Config> {
|
|||||||
Ok(config_builder.finalize())
|
Ok(config_builder.finalize())
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn write_config(file_name: &str, config: Config) -> io::Result<()> {
|
|
||||||
// let mut file = File::create(file_name)?;
|
|
||||||
|
|
||||||
// let config = serde_yaml::to_string(&config)
|
|
||||||
// .map_err(|err| io::Error::new(io::ErrorKind::Other, err.description()))?;
|
|
||||||
|
|
||||||
// file.write_all(config.as_bytes())?;
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn generate_config(
|
pub fn generate_config(
|
||||||
args: Args,
|
args: Args,
|
||||||
connection_string: String,
|
connection_string: String,
|
||||||
@ -82,6 +75,7 @@ pub fn generate_config(
|
|||||||
let function_sources = get_function_sources(&conn)?;
|
let function_sources = get_function_sources(&conn)?;
|
||||||
|
|
||||||
let config = ConfigBuilder {
|
let config = ConfigBuilder {
|
||||||
|
watch: Some(args.flag_watch),
|
||||||
keep_alive: args.flag_keep_alive,
|
keep_alive: args.flag_keep_alive,
|
||||||
listen_addresses: args.flag_listen_addresses,
|
listen_addresses: args.flag_listen_addresses,
|
||||||
connection_string: connection_string,
|
connection_string: connection_string,
|
||||||
@ -94,10 +88,3 @@ pub fn generate_config(
|
|||||||
let config = config.finalize();
|
let config = config.finalize();
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn to_string(config: Config) -> io::Result<String> {
|
|
||||||
// let config = serde_yaml::to_string(&config)
|
|
||||||
// .map_err(|err| io::Error::new(io::ErrorKind::Other, err.description()))?;
|
|
||||||
|
|
||||||
// Ok(config)
|
|
||||||
// }
|
|
||||||
|
12
src/main.rs
12
src/main.rs
@ -75,8 +75,9 @@ fn setup_from_database(args: Args) -> Result<(Config, PostgresPool), std::io::Er
|
|||||||
fn start(args: Args) -> Result<actix::SystemRunner, std::io::Error> {
|
fn start(args: Args) -> Result<actix::SystemRunner, std::io::Error> {
|
||||||
info!("Starting martin v{}", VERSION);
|
info!("Starting martin v{}", VERSION);
|
||||||
|
|
||||||
let (config, pool) = if args.flag_config.is_some() {
|
let config_file_name = args.flag_config.clone();
|
||||||
let file_name = args.flag_config.unwrap();
|
let (config, pool) = if config_file_name.is_some() {
|
||||||
|
let file_name = config_file_name.clone().unwrap();
|
||||||
info!("Using {}", file_name);
|
info!("Using {}", file_name);
|
||||||
setup_from_config(file_name)?
|
setup_from_config(file_name)?
|
||||||
} else {
|
} else {
|
||||||
@ -91,8 +92,13 @@ fn start(args: Args) -> Result<actix::SystemRunner, std::io::Error> {
|
|||||||
std::process::exit(-1);
|
std::process::exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let watch_mode = config.watch || env::var_os("WATCH_MODE").is_some();
|
||||||
|
if watch_mode {
|
||||||
|
info!("Watch mode enabled");
|
||||||
|
}
|
||||||
|
|
||||||
let listen_addresses = config.listen_addresses.clone();
|
let listen_addresses = config.listen_addresses.clone();
|
||||||
let server = server::new(config, pool);
|
let server = server::new(pool, config, watch_mode);
|
||||||
info!("Martin has been started on {}.", listen_addresses);
|
info!("Martin has been started on {}.", listen_addresses);
|
||||||
|
|
||||||
Ok(server)
|
Ok(server)
|
||||||
|
@ -7,7 +7,7 @@ use super::coordinator_actor::CoordinatorActor;
|
|||||||
use super::db::PostgresPool;
|
use super::db::PostgresPool;
|
||||||
use super::db_executor::DbExecutor;
|
use super::db_executor::DbExecutor;
|
||||||
|
|
||||||
pub fn new(config: Config, pool: PostgresPool) -> SystemRunner {
|
pub fn new(pool: PostgresPool, config: Config, watch_mode: bool) -> SystemRunner {
|
||||||
let server = System::new("server");
|
let server = System::new("server");
|
||||||
|
|
||||||
let db = SyncArbiter::start(3, move || DbExecutor(pool.clone()));
|
let db = SyncArbiter::start(3, move || DbExecutor(pool.clone()));
|
||||||
@ -23,6 +23,7 @@ pub fn new(config: Config, pool: PostgresPool) -> SystemRunner {
|
|||||||
coordinator.clone(),
|
coordinator.clone(),
|
||||||
config.table_sources.clone(),
|
config.table_sources.clone(),
|
||||||
config.function_sources.clone(),
|
config.function_sources.clone(),
|
||||||
|
watch_mode,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.bind(listen_addresses.clone())
|
.bind(listen_addresses.clone())
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
---
|
---
|
||||||
# Maximum connections pool size [default: 20]
|
# Database connection string
|
||||||
pool_size: 20
|
connection_string: "postgres://postgres@localhost/test"
|
||||||
|
|
||||||
# Connection keep alive timeout [default: 75]
|
# Connection keep alive timeout [default: 75]
|
||||||
keep_alive: 75
|
keep_alive: 75
|
||||||
|
|
||||||
|
# The socket address to bind [default: 0.0.0.0:3000]
|
||||||
|
listen_addresses: "0.0.0.0:3000"
|
||||||
|
|
||||||
|
# Maximum connections pool size [default: 20]
|
||||||
|
pool_size: 20
|
||||||
|
|
||||||
|
# Enable watch mode
|
||||||
|
watch: false
|
||||||
|
|
||||||
# Number of web server workers
|
# Number of web server workers
|
||||||
worker_processes: 8
|
worker_processes: 8
|
||||||
|
|
||||||
# The socket address to bind [default: 0.0.0.0:3000]
|
|
||||||
listen_addresses: '0.0.0.0:3000'
|
|
||||||
|
|
||||||
# associative arrays of table sources
|
# associative arrays of table sources
|
||||||
table_sources:
|
table_sources:
|
||||||
public.table_source:
|
public.table_source:
|
||||||
|
Loading…
Reference in New Issue
Block a user