improved shutdown

This commit is contained in:
Ivan Yuriev 2024-12-13 18:12:55 +03:00
parent 866d2dc255
commit 0906e227d5
3 changed files with 54 additions and 26 deletions

View File

@ -2,6 +2,7 @@ import gleam/dict.{type Dict}
import gleam/erlang/process.{type Subject}
import gleam/list
import gleam/otp/actor
import gleam/string
import gleam/result.{try}
import json_serde
@ -9,7 +10,7 @@ import query
import simplifile
import tree
import tree_events.{
type TreeEvents, GetEvent, RecursiveGetEvent, SetEvent, Shutdown,
type TreeEvents, GetEvent, RecursiveGetEvent, SetEvent, Shutdown, Snapshot,
}
pub type Message {
@ -95,8 +96,8 @@ fn handle_message(event: TreeEvents, tree) {
SetEvent(path, data, client) -> {
let res = query.set(tree, path, data)
case res {
Error(_) -> {
actor.send(client, res |> result.map(fn(_) { "Ok" }))
Error(err) -> {
actor.send(client, res |> result.map(fn(_) { err |> string.inspect }))
actor.continue(tree)
}
Ok(tree) -> {
@ -105,13 +106,21 @@ fn handle_message(event: TreeEvents, tree) {
}
}
}
Shutdown(filepath) -> {
let json = tree |> json_serde.serialize()
case simplifile.write(filepath, json) {
Error(err) ->
actor.Stop(process.Abnormal(err |> simplifile.describe_error))
Ok(_) -> actor.Stop(process.Normal)
}
Snapshot(filepath, client) -> {
actor.send(client, snapshot(tree, filepath))
actor.continue(tree)
}
Shutdown -> {
actor.Stop(process.Normal)
}
}
}
fn snapshot(tree, filepath) {
let json = tree |> json_serde.serialize()
case simplifile.write(filepath, json) {
Error(err) -> Error(err |> simplifile.describe_error)
Ok(_) -> Ok("Ok")
}
}

View File

@ -16,5 +16,7 @@ pub type TreeEvents {
reply_with: Subject(Result(String, QueryError)),
)
Shutdown(filepath: String)
Snapshot(filepath: String, reply_with: Subject(Result(String, String)))
Shutdown
}

View File

@ -12,13 +12,18 @@ import gleam/otp/actor
import gleam/string
import gleam_community/ansi
import glisten
import query
import query_error
import spinner
import tree_events
import query
import query_error
pub fn main() {
init()
process.sleep_forever()
}
fn init() {
let config = config.load("./config.json") |> io.debug
let forest = case forest.load(config.snapshots_path, config.forest) {
Error(err) -> {
@ -63,7 +68,6 @@ pub fn main() {
}
}
}
actor.continue(state)
})
|> glisten.serve(config.port)
@ -90,19 +94,14 @@ fn read_next(forest) {
case term {
"exit\n" -> {
graceful(forest)
let spinner =
spinner.new("Shutting down...")
|> spinner.with_colour(ansi.pink)
|> spinner.start
process.sleep(5000)
"Bye" |> io.println
spinner |> spinner.stop
}
"help\n" -> {
"Available commands: " |> io.println
"exit" |> io.println
"Available commands:\n" |> io.println
"help\n" |> io.println
"exit\n" |> io.println
read_next(forest)
}
_ -> {
"Unknown command" |> io.println
read_next(forest)
@ -113,13 +112,31 @@ fn read_next(forest) {
}
fn graceful(forest: forest.Forest) {
let spinner =
spinner.new("Shutting down...")
|> spinner.with_colour(ansi.pink)
|> spinner.start
forest.trees
|> dict.to_list
|> list.map(fn(tree) {
|> list.each(fn(tree) {
let ps = tree.1.1
let path = tree.1.0
ps |> process.send(tree_events.Shutdown(path))
{ "Exiting: " <> tree.0 } |> io.println
let res =
ps
|> process.call_forever(fn(actor) { tree_events.Snapshot(path, actor) })
case res {
Ok(ok) -> ok
Error(err) -> err
}
|> io.println
ps |> process.send(tree_events.Shutdown)
})
process.sleep(1000)
"Bye" |> io.println
spinner |> spinner.stop
}