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

View File

@ -16,5 +16,7 @@ pub type TreeEvents {
reply_with: Subject(Result(String, QueryError)), 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/string
import gleam_community/ansi import gleam_community/ansi
import glisten import glisten
import query
import query_error
import spinner import spinner
import tree_events import tree_events
import query
import query_error
pub fn main() { pub fn main() {
init()
process.sleep_forever()
}
fn init() {
let config = config.load("./config.json") |> io.debug let config = config.load("./config.json") |> io.debug
let forest = case forest.load(config.snapshots_path, config.forest) { let forest = case forest.load(config.snapshots_path, config.forest) {
Error(err) -> { Error(err) -> {
@ -63,7 +68,6 @@ pub fn main() {
} }
} }
} }
actor.continue(state) actor.continue(state)
}) })
|> glisten.serve(config.port) |> glisten.serve(config.port)
@ -90,19 +94,14 @@ fn read_next(forest) {
case term { case term {
"exit\n" -> { "exit\n" -> {
graceful(forest) 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" -> { "help\n" -> {
"Available commands: " |> io.println "Available commands:\n" |> io.println
"exit" |> io.println "help\n" |> io.println
"exit\n" |> io.println
read_next(forest) read_next(forest)
} }
_ -> { _ -> {
"Unknown command" |> io.println "Unknown command" |> io.println
read_next(forest) read_next(forest)
@ -113,13 +112,31 @@ fn read_next(forest) {
} }
fn graceful(forest: forest.Forest) { fn graceful(forest: forest.Forest) {
let spinner =
spinner.new("Shutting down...")
|> spinner.with_colour(ansi.pink)
|> spinner.start
forest.trees forest.trees
|> dict.to_list |> dict.to_list
|> list.map(fn(tree) { |> list.each(fn(tree) {
let ps = tree.1.1 let ps = tree.1.1
let path = tree.1.0 let path = tree.1.0
ps |> process.send(tree_events.Shutdown(path))
{ "Exiting: " <> tree.0 } |> io.println { "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
} }