From 3bb731e2d6f26af0575787cbe9b53eb3ae614416 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 13 Jul 2018 14:44:13 -0700 Subject: [PATCH] statemgr: Helper funcs RefreshAndRead and WriteAndPersist In practice these pairs of functions are often used together when working with a "full" statemgr, so these helper wrappers allow us to do that more conveniently. This also introduces a new interface statemgr.Storage, which represents a state manager that has all of the storage capabilities but does not necessarily support locking. In practice callers will usually just use statemgr.Full, but these more-specific interfaces allow us to reflect in APIs which subset of the statemgr functionality each function depends on. --- states/statemgr/helper.go | 41 +++++++++++++++++++++++++++++++++++++ states/statemgr/statemgr.go | 14 +++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 states/statemgr/helper.go diff --git a/states/statemgr/helper.go b/states/statemgr/helper.go new file mode 100644 index 000000000..72486aad6 --- /dev/null +++ b/states/statemgr/helper.go @@ -0,0 +1,41 @@ +package statemgr + +// The functions in this file are helper wrappers for common sequences of +// operations done against full state managers. + +import ( + "github.com/hashicorp/terraform/states" +) + +// RefreshAndRead refreshes the persistent snapshot in the given state manager +// and then returns it. +// +// This is a wrapper around calling RefreshState and then State on the given +// manager. +func RefreshAndRead(mgr Storage) (*states.State, error) { + err := mgr.RefreshState() + if err != nil { + return nil, err + } + return mgr.State(), nil +} + +// WriteAndPersist writes a snapshot of the given state to the given state +// manager's transient store and then immediately persists it. +// +// The caller must ensure that the given state is not concurrently modified +// while this function is running, but it is safe to modify it after this +// function has returned. +// +// If an error is returned, it is undefined whether the state has been saved +// to the transient store or not, and so the only safe response is to bail +// out quickly with a user-facing error. In situations where more control +// is required, call WriteState and PersistState on the state manager directly +// and handle their errors. +func WriteAndPersist(mgr Storage, state *states.State) error { + err := mgr.WriteState(state) + if err != nil { + return err + } + return mgr.PersistState() +} diff --git a/states/statemgr/statemgr.go b/states/statemgr/statemgr.go index 355eef055..672f10a9f 100644 --- a/states/statemgr/statemgr.go +++ b/states/statemgr/statemgr.go @@ -1,5 +1,16 @@ package statemgr +// Storage is the union of Transient and Persistent, for state managers that +// have both transient and persistent storage. +// +// Types implementing this interface coordinate between their Transient +// and Persistent implementations so that the persistent operations read +// or write the transient store. +type Storage interface { + Transient + Persistent +} + // Full is the union of all of the more-specific state interfaces. // // This interface may grow over time, so state implementations aiming to @@ -10,7 +21,6 @@ package statemgr // // var _ statemgr.Full = (*ImplementingType)(nil) type Full interface { - Transient - Persistent + Storage Locker }