mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
[MIRROR] Add system for safely manipulating JSON databases and apply it to photo albums and photo frames [MDB IGNORE] (#25887)
* Add system for safely manipulating JSON databases and apply it to photo albums and photo frames (#80519) We frequently have issues with data loss in our long storage .json files for various reasons, such as the file being completely blanked out on write etc. This introduces a system that tries to safely handle that by saving the known working json file into a backup that will be loaded in the case a write fails. This system queues updates in order to send through to the next tick. This is an improvement over the existing implementation of photo albums and photo frames (I think all persistence, even) which do not save until the end of a properly rebooted round, but not during a server crash. Also saves the jsons in pretty prints, which make them easier to read but especially make them easier to diff in a git repository, which MSO wants to setup (and hopefully make public so I can make a dashboard on bus.moth.fans for looking at photo albums and their history, which is something I've wanted to do for a very long time). ## Changelog 🆑 refactor: Photo albums and photo frames are now more resilient to data loss, especially when a server crashes. /🆑 * Add system for safely manipulating JSON databases and apply it to photo albums and photo frames --------- Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
@@ -20,8 +20,23 @@ SUBSYSTEM_DEF(persistence)
|
||||
var/list/blocked_maps = list()
|
||||
var/list/saved_trophies = list()
|
||||
var/list/picture_logging_information = list()
|
||||
var/list/obj/structure/sign/picture_frame/photo_frames
|
||||
var/list/obj/item/storage/photo_album/photo_albums
|
||||
|
||||
/// A json_database linking to data/photo_frames.json.
|
||||
/// Schema is persistence_id => array of photo names.
|
||||
var/datum/json_database/photo_frames_database
|
||||
|
||||
/// A lazy list of every picture frame that is going to be loaded with persistent photos.
|
||||
/// Will be null'd once the persistence system initializes, and never read from again.
|
||||
var/list/obj/structure/sign/picture_frame/queued_photo_frames
|
||||
|
||||
/// A json_database linking to data/photo_albums.json.
|
||||
/// Schema is persistence_id => array of photo names.
|
||||
var/datum/json_database/photo_albums_database
|
||||
|
||||
/// A lazy list of every photo album that is going to be loaded with persistent photos.
|
||||
/// Will be null'd once the persistence system initializes, and never read from again.
|
||||
var/list/obj/item/storage/photo_album/queued_photo_albums
|
||||
|
||||
var/rounds_since_engine_exploded = 0
|
||||
var/delam_highscore = 0
|
||||
var/tram_hits_this_round = 0
|
||||
@@ -48,7 +63,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
save_prisoner_tattoos()
|
||||
collect_trophies()
|
||||
collect_maps()
|
||||
save_photo_persistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
|
||||
save_randomized_recipes()
|
||||
save_scars()
|
||||
save_custom_outfits()
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
///Loads up the photo album source file.
|
||||
/datum/controller/subsystem/persistence/proc/get_photo_albums()
|
||||
var/album_path = file("data/photo_albums.json")
|
||||
if(fexists(album_path))
|
||||
return json_decode(file2text(album_path))
|
||||
|
||||
///Loads up the photo frames source file.
|
||||
/datum/controller/subsystem/persistence/proc/get_photo_frames()
|
||||
var/frame_path = file("data/photo_frames.json")
|
||||
if(fexists(frame_path))
|
||||
return json_decode(file2text(frame_path))
|
||||
|
||||
/// Removes the identifier of a persistent photo frame from the json.
|
||||
/datum/controller/subsystem/persistence/proc/remove_photo_frames(identifier)
|
||||
var/frame_path = file("data/photo_frames.json")
|
||||
@@ -25,62 +13,23 @@
|
||||
|
||||
///Loads photo albums, and populates them; also loads and applies frames to picture frames.
|
||||
/datum/controller/subsystem/persistence/proc/load_photo_persistence()
|
||||
var/album_path = file("data/photo_albums.json")
|
||||
var/frame_path = file("data/photo_frames.json")
|
||||
if(fexists(album_path))
|
||||
var/list/json = json_decode(file2text(album_path))
|
||||
if(json.len)
|
||||
for(var/i in photo_albums)
|
||||
var/obj/item/storage/photo_album/A = i
|
||||
if(!A.persistence_id)
|
||||
continue
|
||||
if(json[A.persistence_id])
|
||||
A.populate_from_id_list(json[A.persistence_id])
|
||||
|
||||
if(fexists(frame_path))
|
||||
var/list/json = json_decode(file2text(frame_path))
|
||||
if(json.len)
|
||||
for(var/i in photo_frames)
|
||||
var/obj/structure/sign/picture_frame/PF = i
|
||||
if(!PF.persistence_id)
|
||||
continue
|
||||
if(json[PF.persistence_id])
|
||||
PF.load_from_id(json[PF.persistence_id])
|
||||
|
||||
///Saves the contents of photo albums and the picture frames.
|
||||
/datum/controller/subsystem/persistence/proc/save_photo_persistence()
|
||||
var/album_path = file("data/photo_albums.json")
|
||||
var/frame_path = file("data/photo_frames.json")
|
||||
|
||||
var/list/frame_json = list()
|
||||
var/list/album_json = list()
|
||||
|
||||
if(fexists(album_path))
|
||||
album_json = json_decode(file2text(album_path))
|
||||
fdel(album_path)
|
||||
|
||||
for(var/i in photo_albums)
|
||||
var/obj/item/storage/photo_album/A = i
|
||||
if(!istype(A) || !A.persistence_id)
|
||||
photo_albums_database = new("data/photo_albums.json")
|
||||
for (var/obj/item/storage/photo_album/album as anything in queued_photo_albums)
|
||||
if (isnull(album.persistence_id))
|
||||
continue
|
||||
var/list/L = A.get_picture_id_list()
|
||||
album_json[A.persistence_id] = L
|
||||
|
||||
album_json = json_encode(album_json)
|
||||
var/album_data = photo_albums_database.get_key(album.persistence_id)
|
||||
if (!isnull(album_data))
|
||||
album.populate_from_id_list(album_data)
|
||||
|
||||
WRITE_FILE(album_path, album_json)
|
||||
|
||||
if(fexists(frame_path))
|
||||
frame_json = json_decode(file2text(frame_path))
|
||||
fdel(frame_path)
|
||||
|
||||
for(var/i in photo_frames)
|
||||
var/obj/structure/sign/picture_frame/F = i
|
||||
if(!istype(F) || !F.persistence_id)
|
||||
photo_frames_database = new("data/photo_frames.json")
|
||||
for (var/obj/structure/sign/picture_frame/frame as anything in queued_photo_frames)
|
||||
if (isnull(frame.persistence_id))
|
||||
continue
|
||||
frame_json[F.persistence_id] = F.get_photo_id()
|
||||
|
||||
frame_json = json_encode(frame_json)
|
||||
|
||||
WRITE_FILE(frame_path, frame_json)
|
||||
var/frame_data = photo_frames_database.get_key(frame.persistence_id)
|
||||
if (!isnull(frame_data))
|
||||
frame.load_from_id(frame_data)
|
||||
|
||||
queued_photo_albums = null
|
||||
queued_photo_frames = null
|
||||
|
||||
Reference in New Issue
Block a user