Backup level every 15 minutes

This commit is contained in:
Scott Wadden 2023-12-09 00:43:08 -04:00
parent bcb6932ed1
commit 1d8d97169d
4 changed files with 39 additions and 10 deletions

View File

@ -14,7 +14,7 @@ const
nim_dlls = ["pcre64.dll"]
godot_opts = "target=release_debug"
version = "0.2.0"
version = "0.2.2"
author = "Scott Wadden"
description = "Logo-like DSL for Godot"
license = "MIT"
@ -36,7 +36,8 @@ requires "nim >= 1.6.10",
"chronicles",
"dotenv",
"nimibook",
"metrics"
"metrics",
"zippy"
proc godot_bin(target = target): string =
result = this_dir() & &"/vendor/godot/bin/godot.{target}.opt.tools.{cpu}{exe_ext}"

View File

@ -1,5 +1,5 @@
import std / [locks, os, random, net]
import std / times except seconds
import std / times except seconds, minutes
from pkg / netty import Reactor
import core, models, models / [serializers], libs / [interpreters, eval]
import ./ [vars, host_bridge, scripting]
@ -278,7 +278,9 @@ proc worker_thread(params: (ZenContext, GameState)) {.gcsafe.} =
const max_time = (1.0 / 30.0).seconds
const min_time = (1.0 / 120.0).seconds
const auto_save_interval = 30.seconds
const backup_interval = 15.minutes
var save_at = get_mono_time() + auto_save_interval
var backup_at = MonoTime.low
try:
while running:
@ -324,13 +326,18 @@ proc worker_thread(params: (ZenContext, GameState)) {.gcsafe.} =
for unit in batched:
unit.apply_changes
if get_mono_time() > save_at:
save_level(state.config.level_dir)
save_at = get_mono_time() + auto_save_interval
let now = get_mono_time()
let frame_end = get_mono_time()
if frame_end < wait_until:
sleep int((wait_until - frame_end).in_milliseconds)
if now > save_at:
save_level(state.config.level_dir)
save_at = now + auto_save_interval
if now > backup_at:
backup_level(state.config.level_dir)
backup_at = now + backup_interval
if now < wait_until:
sleep int((wait_until - get_mono_time()).in_milliseconds)
except Exception as e:
error "Unhandled worker thread exception", kind = $e.type, msg = e.msg,

View File

@ -19,6 +19,9 @@ import pkg / [pretty, flatty]
export with, sets, tables, pretty, flatty
proc minutes*(m: float | int): Duration {.inline.} =
init_duration(seconds = int(m * 60))
### Debug
export dump

View File

@ -1,4 +1,5 @@
import std / [json, jsonutils, sugar, tables, strutils, os]
import std / [json, jsonutils, sugar, tables, strutils, os, times, algorithm]
import pkg / zippy / ziparchives_v1
import core except to_json
import models
import controllers / script_controllers / scripting
@ -167,6 +168,23 @@ proc save_level*(level_dir: string, save_all = false) =
else:
debug "not server. Skipping save."
proc backup_level*(level_dir: string) =
if Server in state.local_flags:
let backup_dir = state.config.world_dir / "backups"
create_dir backup_dir
let backup_file = backup_dir / state.config.level & "_" &
times.now().format("yyyy-MM-dd-HH-mm-ss") & ".zip"
let backups = walk_files(backup_dir /
state.config.level & "_????-??-??-??-??-??.zip").to_seq.sorted
if backups.len > 19:
for file in backups[0..^20]:
remove_file file
create_zip_archive(level_dir, backup_file)
proc load_units(parent: Unit) =
let opts = JOptions(allow_missing_keys: true)
let path =