Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DYN-6470 Improve Dynamo PreferenceSettings.Instance singleton behavior. #14658

Merged
merged 5 commits into from
Dec 4, 2023

Conversation

saintentropy
Copy link
Contributor

@saintentropy saintentropy commented Nov 30, 2023

Purpose

The purpose of the PR is to improve the singleton behavior of the PreferenceSettings.Instance. Currently it is very easy to utilize the Instance with the assumption that it is connected to the DynamoModel.PrefenceSettings (previously how you would access runtime Preferences via API) and will stay in sync. This is not the case and they can diverge in state and data can be lost regardless of how often the Preference are saved to disk by the API user. This PR improve the Instance method synchronization by connecting directly to the DynamoModel.PreferenceSettings when it is available. There are still scenarios where the two access points can get out of sync but this should change cover most scenarios until we can unify the access points to a single reference object.

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated
  • This PR contains no files larger than 50 MB

Release Notes

Reviewers

@QilongTang @mjkkirschner @BogdanZavu

FYIs

@twastvedt

@@ -492,6 +492,9 @@ protected virtual void ShutDownCore(bool shutdownHost)
Dispose();
PreferenceSettings.SaveInternal(pathManager.PreferenceFilePath);

//Remove reference on shutdown
PreferenceSettings.dynamoModelRuntimePreferenceSettings = null;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need to do this but may be good due to not being able to properly discuss the DynamoModel on shutdown.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discuss == dispose?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is likely safe on DynamoModel if you ensure that dynamoModelRuntimePreferenceSettings is always reset to something valid on startup.

Can you add a test for that?

@QilongTang QilongTang added this to the 3.0 milestone Nov 30, 2023
internal readonly static Lazy<PreferenceSettings>
lazy = new Lazy<PreferenceSettings>
(() => PreferenceSettings.Load(PathManager.Instance.PreferenceFilePath));

[XmlIgnore]
public static PreferenceSettings Instance { get { return lazy.Value; } }
public static PreferenceSettings Instance { get { return dynamoModelRuntimePreferenceSettings ?? lazy.Value; } }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so now Dynamo supports local instances of Preferences, a singleton instance which can be loaded from disk, or set to incoming local Preferences instances during the DynamoModel construction (not all the time though).
We need a followup to untangle all of this before it gets out of hand.

At the moment I would not be able to predict what instance of the Preferences class would be used at a given spot in Dynamo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes throughly needs to be cleaned up. I would consider this a bandaid to resolve the current out of sync behavior. Fundamentally the issue (and to your question above @QilongTang ) is that from an API consumer perspective (like the Player) if you goal is to make changes to Preferences while Dynamo is open and you want those changes persisted you need to interact with the runtime Presence that is held by DynamoModel. It will aways keep the state for the application and overwrite its state to disk when Dynamo Shuts down. If I grab Instance ,make changes and also know to save things it doesn't matter at all. DynamoModel.PreferenceSettings wins.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand the behavior today on first time start-up (ie no existing preference XML)
SplashScreen calls PreferenceSettings.Instance
Instance creates a new PreferenceSettings object.
DynamoModel start is passed the new PreferenceSettings object.
DynamoModel performs additional initialization on the new PrefenceSettings object
Eventually DynamoModel shutdown saves the PreferenceSettings to disk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the theme of this PR is looking at all the times Dynamo Player is using PreferenceSettings.Instance AKA DynamoPreferences singleton we were expecting to have the Runtime Preferences object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only other way I can think to work this way is make the PrefenceSettings always update if the disk is changed and always write to disk any time any properties are updated. That would also could be fragile due to concurrency issues... Other option is to actually get to a real singleton.

Copy link
Contributor

@QilongTang QilongTang Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aparajit-pratap You are for sure on spot, that was exactly what our team was supposed to change! But this might be a much heavier change than this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can give it a shot. I believe one a lazy value is set it doesn't recall the into function over and over.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main issue will be all the special handling we do for testing but let's see

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we currently don't let anyone just set the DynamoModel.Prefence it is readonly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is why we can keep it for the time being if we're worried about API breaks and simply reroute it to PreferenceSettings.Instance in its getter:

[Obsolete("this will be removed in 4.0")]
public readonly PreferenceSettings PreferenceSettings { get {return PreferenceSettings.Instance;} }

@@ -304,7 +304,8 @@ internal static string AppVersion
/// <summary>
/// Preference settings for this instance of Dynamo.
/// </summary>
public readonly PreferenceSettings PreferenceSettings;
[Obsolete("this will be removed in 4.0")]
Copy link
Contributor

@aparajit-pratap aparajit-pratap Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just meant 4.0 as an example, maybe just mention a future release of Dynamo instead of committing to a specific release.

@saintentropy
Copy link
Contributor Author

One failing test is expected. Merging now

@saintentropy saintentropy merged commit d8db34e into DynamoDS:master Dec 4, 2023
20 of 21 checks passed
@saintentropy saintentropy deleted the DYN-6470 branch December 4, 2023 19:18
@saintentropy saintentropy mentioned this pull request Dec 11, 2023
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants