Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • no upgrade method. The store should handle upgrades transparently during startup/open. This is considered a fault in the original API
  • no visit method. Rather the open (or similar) method should take a visitor to handle initial loading of the data. See below for more detail.

API is in terms of Preferences PreferenceRecords (analogous to ConfiguredObjectRecords) which have minimal knowledge of the internal structure except from the UUID. The ID is necessary to identify records for deletion and update operations.

Broker and VirtualHost have separate preference stores.

...

Code Block
languagejava
interface PreferenceStore
{
    void open(PreferenceStoreUpdateVisitor updateVisitor, PreferenceStoreOpenVisitor openVisitor, PreferenceStoreResolveVisitor resolveVisitor, PreferenceStoreAttachVisitor attachVisitor);

    void close(PreferenceStoreCloseVisitor closeVisitor// see below for the Updater and Recoverer interfaces
    void open(PreferenceStoreUpdater updater, PreferenceStoreRecoverer recoverer);

    // safely persist all state and close all resources
    void close();

    // adds preferences to the store
    void create(Collection<Preference>Collection<PreferenceRecord> preferencepreferences);

    // updates existing preferences. throws an exception if preference with given id is not already in the store
    void update(Collection<Preference>Collection<PreferenceRecord> preferencepreferences);

    // updates existing preferences. if a preference with given id is not already in the store it will be added
    void updateOrCreate(Collection<Preference>Collection<PreferenceRecord> preferencepreferences);

    // remove preferences from the store. throws an exception if preference with given id is not already in the store
    void delete(Collection<Preference>Collection<PreferenceRecord> preferencepreferences);
}

Recovery



interface PreferenceRecord
{
    UUID getId();
	Map<String, Object> getAttributes();
}

Recovery

At recovery time the PreferenceRecords in the PreferenceStore will need to be converted into At recovery time the PreferenceStores' parents will need to read all the preferences from their respective stores and create Preference objects. This needs to occur after the configured objects are recovered. In this phase, objects corresponding to the records must be created. The recovery algorithm will be similar to that of configured object recovery as preferences may reference other preferences, so some preferences (Dashboards) may have to await the creation of others before they may be created. As preferences are created they need to be assigned to their associated configured object.

...

  • we want to ability to update individual preferences. This may include updating, creating and deleting preferences. This might require multiple passes.
  • Since the update step might arbitrarily modify the preferences it might not be sensible or feasible to instantiate the type specific PreferenceValue. During this step the PreferenceValue is simply a GenericPreferenceValue (i.e., Map<String, Object>)
    In the PreferenceStoreOpenVisitor should turn the GenericPreferenceValue into a type specific PreferenceValuethe store needs to be informed about the changes so that the update can be persisted.
  • preferences need to ability to reference each other. One way to achieve this is that separate instantiation and dependency resolution.

The first to points are the responsibility of the PreferenceStoreUpdater while the second should be performed by the PreferenceStoreRecoverer.

While not part of this specification the recoverer should probably go through these steps

  1. Convert PreferenceRecord to Preference
  2. Attach Preference to AbstractConfiguredObject
  3. Convert generic attributes to a type specific PreferenceValue
  4. Cross link to other preferences
Code Block
languagejava

interface PreferenceStoreUpdater
{
    Collection<PreferenceRecord> updatePreferences(Collection<PreferenceRecord> preferences);
}

interface PreferenceStoreRecoverer
{
	void recoverPreferences(Collection<PreferenceRecord> preferences);
}

Code Block
languagejava
interface PreferenceStoreUpdateVisitor
{
    // Notifies the visitor that a new pass is commencing
    void beginUpdatePass();

    // Called for every preference currently in the store
    // The Preference p will be replaced with whatever the method returns. Let us consider three cases
    //   a) the collection is empty: The preference is deleted
    //   b) the collection contains a single preference with the same id as p: the preference is updated
    //   c) the collection has multiple preferences: new preferences are created
    Collection<Preference> visitForUpdate(Preference p);

    // Notifies the visitor that a pass completed.
    // The store should treat a step as incomplete until endUpdatePass returns true. Only then should any changes be made persistent.
    // @return true to indicate that no further pass is necessary
    // @return false to indicate that another update pass should be performed
    boolean endUpdatePass();
}

interface PreferenceStoreOpenVisitor
{
    // Notifies the visitor that a new pass is commencing
    void beginOpenPass();

    // Called for every preference currently in the store
    // The Preference p will be replaced with whatever the method returns.
    // This should turn the GenericPreferenceValue into a type-specific PreferenceValue
    PreferenceValue visitForOpen(String type, Map<String, Object> preferenceValueAttributes);

    // see above
    boolean endOpenPass();
}

interface PreferenceStoreResolveVisitor
{
    // Notifies the visitor that a new pass is commencing
    void beginResolvePass();

    // Called for every preference currently in the store
    // The Preference p will be replaced with whatever the method returns.
    Preference visitForResolve(Preference p);

    // see above
    boolean endResolvePass();
}

interface PreferenceStoreCloseVisitor
{
    // Notifies the visitor that a new pass is commencing
    void beginClosePass();

    // Called for every preference currently in the store
    // The store will write to disk whatever this method returns.
    Preference visitForClose(Preference p);

    // see above
    boolean endClosePass();
} 

Persistence

Preferences are considered immutable. All changes to preferences should go through a UserPreferences facade which is responsible for updating the store.

...