Merge branch 'save_thing_settings_on_demand' into 'v3'

Make it possible to manually save all settings to disk

See merge request openflexure/openflexure-microscope-server!171
This commit is contained in:
Richard Bowman 2024-01-15 21:20:33 +00:00
commit 06bc5f65cb
2 changed files with 53 additions and 4 deletions

View file

@ -7,12 +7,21 @@ the server.
""" """
from collections.abc import Mapping from collections.abc import Mapping
from socket import gethostname from socket import gethostname
from typing import Any, MutableMapping, Optional, Sequence from typing import Annotated, Any, MutableMapping, Optional, Sequence
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from fastapi import HTTPException from fastapi import Depends, HTTPException, Request
from labthings_fastapi.dependencies.metadata import GetThingStates from labthings_fastapi.dependencies.metadata import GetThingStates
from labthings_fastapi.thing import Thing from labthings_fastapi.thing import Thing
from labthings_fastapi.decorators import thing_action, thing_property from labthings_fastapi.decorators import thing_action, thing_property
from labthings_fastapi.thing_server import find_thing_server, ThingServer
from labthings_fastapi.dependencies.invocation import InvocationLogger
def thing_server_from_request(request: Request) -> ThingServer:
return find_thing_server(request.app)
ThingServerDep = Annotated[ThingServer, Depends(thing_server_from_request)]
def recursive_update(old_dict: MutableMapping, update: Mapping): def recursive_update(old_dict: MutableMapping, update: Mapping):
@ -122,4 +131,31 @@ class SettingsManager(Thing):
subdict[kl[-1]] = v subdict[kl[-1]] = v
except KeyError: except KeyError:
continue continue
return state return state
@thing_action
def save_all_thing_settings(self, thing_server: ThingServerDep, logger: InvocationLogger) -> None:
"""Ensure all the Things sync their settings to disk.
Normally, each Thing has a `thing_settings` attribute that can be
used to save settings. That dictionary is saved to a JSON file
when the server shuts down cleanly.
This action causes all the `thing_settings` dictionaries to be
saved to files immediately, meaning that settings will not be
lost in the event of a server crash, power outage, etc.
"""
for name, thing in thing_server.things.items():
try:
if thing._labthings_thing_settings:
thing._labthings_thing_settings.write_to_file()
logger.info(f"Wrote {name} settings to disk.")
except PermissionError:
logger.warning(
f"Could not write {name} settings to disk: permission error."
)
except FileNotFoundError:
logger.warning(
f"Could not write {name} settings, folder not found"
)

View file

@ -71,6 +71,11 @@
</tabIcon> </tabIcon>
</li> </li>
</ul> </ul>
<task-submitter
:submit-url="saveAllThingSettingsUri"
submit-label="Save all settings"
class="uk-margin"
/>
</div> </div>
<div class="view-component uk-width-expand uk-padding-small"> <div class="view-component uk-width-expand uk-padding-small">
<tabContent <tabContent
@ -137,6 +142,7 @@ import stageSettings from "./settingsComponents/stageSettings.vue";
// Import generic components // Import generic components
import tabIcon from "../genericComponents/tabIcon"; import tabIcon from "../genericComponents/tabIcon";
import tabContent from "../genericComponents/tabContent"; import tabContent from "../genericComponents/tabContent";
import TaskSubmitter from '../genericComponents/taskSubmitter.vue';
// Export main app // Export main app
export default { export default {
@ -150,7 +156,8 @@ export default {
appSettings, appSettings,
featuresSettings, featuresSettings,
tabIcon, tabIcon,
tabContent tabContent,
TaskSubmitter
}, },
data: function() { data: function() {
@ -160,6 +167,12 @@ export default {
}; };
}, },
computed: {
saveAllThingSettingsUri() {
return this.thingActionUrl("settings", "save_all_thing_settings");
}
},
methods: { methods: {
setTab: function(event, tab) { setTab: function(event, tab) {
if (!(this.currentTab == tab)) { if (!(this.currentTab == tab)) {