-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Guillaume Hivert <[email protected]>
- Loading branch information
Showing
10 changed files
with
177 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,46 @@ | ||
import backend/config.{type Config} | ||
import backend/postgres | ||
import backend/router | ||
import dot_env | ||
import gleam/erlang/process | ||
import gleam/otp/supervisor | ||
import mist | ||
import periodic | ||
import setup | ||
import wisp | ||
|
||
pub fn main() { | ||
setup.radiate() | ||
wisp.configure_logger() | ||
dot_env.load() | ||
|
||
let secret_key_base = setup.get_secret_key_base() | ||
let secret_key_base = config.get_secret_key_base() | ||
let cnf = config.read_config() | ||
|
||
let assert Ok(_) = | ||
wisp.mist_handler(router.handle_request, secret_key_base) | ||
router.handle_request(_, cnf) | ||
|> wisp.mist_handler(secret_key_base) | ||
|> mist.new() | ||
|> mist.port(3000) | ||
|> mist.start_http() | ||
|
||
process.sleep_forever() | ||
} | ||
|
||
fn supervise(start: fn() -> _) { | ||
use children <- supervisor.start() | ||
supervisor.add(children, { | ||
use _ <- supervisor.worker() | ||
start() | ||
}) | ||
} | ||
|
||
fn sync_hex(cnf: Config) { | ||
let db = postgres.connect(cnf) | ||
Ok(True) | ||
} | ||
|
||
fn start_hex_sync(cnf: Config) { | ||
use <- supervise() | ||
periodic.periodically(do: fn() { sync_hex(cnf) }, waiting: 60 * 1000) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import gleam/erlang/os | ||
import gleam/pgo | ||
import wisp | ||
|
||
pub type Context { | ||
Context(connection: pgo.Connection) | ||
} | ||
|
||
pub type Config { | ||
Config(database_url: String) | ||
} | ||
|
||
pub fn read_config() { | ||
let assert Ok(database_url) = os.get_env("DATABASE_URL") | ||
Config(database_url) | ||
} | ||
|
||
pub fn get_secret_key_base() { | ||
wisp.random_string(64) | ||
} | ||
|
||
pub fn is_dev() { | ||
os.get_env("GLEAM_ENV") == Ok("development") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import backend/config.{type Config, type Context, Context} | ||
import gleam/dynamic | ||
import gleam/int | ||
import gleam/list | ||
import gleam/option.{Some} | ||
import gleam/pgo.{Config} | ||
import gleam/regex | ||
import gleam/result | ||
import wisp.{type Response} | ||
|
||
pub fn connect(cnf: Config) { | ||
let assert Ok(config) = parse_database_url(cnf.database_url) | ||
config | ||
|> pgo.connect() | ||
|> Context | ||
} | ||
|
||
pub fn middleware(cnf: Config, handler: fn(Context) -> Response) { | ||
connect(cnf) | ||
|> handler() | ||
} | ||
|
||
fn database_url_matcher() { | ||
"postgres://(.*):(.*)@(.*):(.*)/(.*)" | ||
|> regex.from_string() | ||
|> result.replace_error(Nil) | ||
} | ||
|
||
fn parse_database_url(database_url: String) -> Result(pgo.Config, _) { | ||
use matcher <- result.map(database_url_matcher()) | ||
let matches = regex.scan(with: matcher, content: database_url) | ||
use cnf, data, index <- list.index_fold(matches, pgo.default_config()) | ||
case index { | ||
0 -> Config(..cnf, user: data.content) | ||
1 -> Config(..cnf, password: Some(data.content)) | ||
2 -> Config(..cnf, host: data.content) | ||
3 -> Config(..cnf, port: result.unwrap(int.parse(data.content), 5432)) | ||
4 -> Config(..cnf, database: data.content) | ||
_ -> cnf | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import gleam/erlang/process.{type Subject} | ||
import gleam/io | ||
import gleam/function | ||
import gleam/otp/actor | ||
import gleam/result | ||
|
||
// import packages/error.{type Error} | ||
|
||
pub opaque type Message { | ||
Rerun | ||
} | ||
|
||
type State(a) { | ||
State(self: Subject(Message), work: fn() -> Result(a, Nil), interval: Int) | ||
} | ||
|
||
/// Repeatedly call a function, leaving `interval` milliseconds between each | ||
/// call. | ||
/// When the `work` function returns an error it is printed. | ||
pub fn periodically( | ||
do work: fn() -> Result(a, Nil), | ||
waiting interval: Int, | ||
) -> Result(Subject(Message), actor.StartError) { | ||
fn() { init(interval, work) } | ||
|> actor.Spec(loop: loop, init_timeout: 100) | ||
|> actor.start_spec() | ||
} | ||
|
||
fn init( | ||
interval: Int, | ||
work: fn() -> Result(a, Nil), | ||
) -> actor.InitResult(State(a), Message) { | ||
let subject = process.new_subject() | ||
let state = State(subject, work, interval) | ||
process.new_selector() | ||
|> process.selecting(subject, function.identity) | ||
|> fn(selector) { | ||
enqueue_next_rerun(state) | ||
actor.Ready(state, selector) | ||
} | ||
} | ||
|
||
fn loop(message: Message, state: State(a)) -> actor.Next(Message, State(a)) { | ||
case message { | ||
Rerun -> { | ||
let _ = result.map_error(state.work(), io.debug) | ||
enqueue_next_rerun(state) | ||
actor.continue(state) | ||
} | ||
} | ||
} | ||
|
||
fn enqueue_next_rerun(state: State(a)) { | ||
process.send_after(state.self, state.interval, Rerun) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import backend/postgres | ||
import backend/config.{type Config} | ||
|
||
pub fn sync(cnf: Config) { | ||
let ctx = postgres.connect(cnf) | ||
} |