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

Added settings manager #1645

Merged

Conversation

mamaso
Copy link

@mamaso mamaso commented Apr 26, 2016

Addresses some of the comments in #1559

Highlighting relevant pieces:

Two relevant configuration settings:

  • enableConfigChanges: on/off for the whole dynamic settings piece, default off
  • lockDefinedSettings: on/off for locking config specified settings, default on.

Settings Manager

settings / cache / db management

Parse Server Constructor:

  1. db settings pulled
  2. cached settings updated if necessary
  3. cached settings pushed to db
  4. ParseServer.config.settingsInitialized promise to track state (code smell, but needs a more significant api change otherwise)

SettingsRouter:

  • All ops require master key
  • POST
    • return error if enableConfigChanges is not true
    • updates values & persists IFF current & update are different
    • returns object with only values which were updated
  • GET
    • returns all unlocked settings
    • if a setting is undefined in server configuration, it will appear as null

middlewares.handleParseHeaders:

  • fetches database configuration & updates cache once per request IFF enableConfigChanges true


function getSettingsCollection() {
let config = cache.apps.get(appId);
return database.getDatabaseConnection(appId, config.collectionPrefix).adaptiveCollection(settingsCollectionName);
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't want to introduce new uses of collectionPrefix inside Parse Server. You should go through the database adapter to retrieve the collection, that will apply the prefix automatically, and also let you avoid referencing the appId in here, I think.

Copy link
Author

Choose a reason for hiding this comment

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

Can you give me a code snippet? Not sure how I can get access to the current dbController without the getDatabaseConnection code.

Copy link
Contributor

@drew-gross drew-gross Apr 26, 2016

Choose a reason for hiding this comment

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

once you have a config it's just config.database.adapter. You can see the API in MongoStorageAdapter and MongoCollection although I'm changing a lot of stuff in there recently.

@drew-gross
Copy link
Contributor

drew-gross commented Apr 26, 2016

A few suggestions but generally this looks good. Also looks like there are a few failing tests to fix.

@ghost
Copy link

ghost commented Apr 27, 2016

@mamaso updated the pull request.

@codecov-io
Copy link

codecov-io commented Apr 27, 2016

Current coverage is 92.21%

Merging #1645 into settings-endpoint will increase coverage by -0.58%

  1. 4 files in src were modified. more
    • Misses +3
    • Partials -1
    • Hits +14
  2. 9 files (not in diff) in src/authDataManager were modified. more
    • Misses +11
    • Hits +13
  3. 15 files (not in diff) in src/Routers were modified. more
    • Misses +35
    • Hits +95
  4. 10 files (not in diff) in src/LiveQuery were modified. more
    • Misses +7
    • Hits +44
  5. 8 files (not in diff) in src/Controllers were modified. more
    • Misses +1
    • Hits +72
  6. 3 files (not in diff) in ...apters/Storage/Mongo were modified. more
    • Misses +1
    • Hits +28
  7. 2 files (not in diff) in src/Adapters/Logger were modified. more
    • Misses +7
    • Hits +2
  8. 2 files (not in diff) in src/Adapters/Files were modified. more
    • Misses +4
    • Hits +12
  9. 2 files (not in diff) in src/Adapters were modified. more
    • Misses +3
  10. 14 files (not in diff) in src were modified. more
    • Misses +17
    • Partials -9
    • Hits +183
@@           settings-endpoint      #1645   diff @@
===================================================
  Files                     87         88      +1   
  Lines                   5455       6098    +643   
  Methods                    0       1077   +1077   
  Branches                1005       1212    +207   
===================================================
+ Hits                    5063       5623    +560   
- Misses                   382        475     +93   
+ Partials                  10          0     -10   

Powered by Codecov. Last updated by 4462145...430a61f

@@ -43,9 +43,9 @@ var defaultConfiguration = {
};

// Set up a default API server for testing with default configuration.
var api = new ParseServer(defaultConfiguration);
global.parseServerObject = new ParseServer(defaultConfiguration);
Copy link
Contributor

@drew-gross drew-gross Apr 27, 2016

Choose a reason for hiding this comment

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

Can you adjust these tests to not need global variables please? I'd suggest fetching everything you need for tests from the HTTP api rather than looking at the object itself. Then it's more of an end-to-end test as well.

Copy link
Author

@mamaso mamaso Apr 27, 2016

Choose a reason for hiding this comment

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

Yeah, this is an ugly side effect of the pull/update/push promise behavior that happens in the constructor.

Adjusted so that setServerConfiguration returns the constructed parse server object instead of using a new global, is that a fair compromise?

The tests are split into two groups: testing ParseServer constructor behavior & testing the settings router e2e. Testing the constructor behavior benefits from having the constructed Parse Server object.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah that seems like a good solution.

@drew-gross
Copy link
Contributor

drew-gross commented Apr 27, 2016

Cool, just a couple more changes. We usually use () for anonymous functions that take no arguments instead of _, _ is actually a valid variable name in JavaScript so using _ could be a little more confusing and potentially abused later. No need to change it in this PR (unless you feel like it) but in future ones could you use that style?

@mamaso
Copy link
Author

mamaso commented Apr 27, 2016

Yeah, that makes a lot of sense why one might avoid _, I'll add in that change as I'm making some anyway.

A question for you: do you have any ideas for how to make hidden/locked settings easier to manage? I considered going with a convention based approach where if a new setting was added to the cache that had a name containing 'manager' or 'controller' we would treat it as hidden. Ideally this settings piece would automatically work for new settings without any code changes.

@drew-gross
Copy link
Contributor

I think the safest option for now would be to have a whitelist of settings that appear. That way we can avoid any unintentional effects, and as we see how people use this in practice and how the dashboard uses the settings, we can get a better feel for the problem and what might make sense for future default behaviour. I'm also beginning to wonder if it might actually be better to see if we can simplify the 2 additional settings into 1 or even 0 additional settings for now, so that we can what problems have been solved and what problems aren't yet solved before adding more complexity.

If you haven't looked at the /serverInfo endpoint yet, I'd suggest you check that out as well, it's used extensively by the dashboard and might be relevant here.

@ghost
Copy link

ghost commented Apr 28, 2016

@mamaso updated the pull request.

@ghost
Copy link

ghost commented Apr 28, 2016

@mamaso updated the pull request.

@mamaso mamaso closed this Apr 28, 2016
@mamaso mamaso reopened this Apr 28, 2016
@mamaso
Copy link
Author

mamaso commented Apr 28, 2016

The CI errors seem to be inconsistent timeout issues with various tests, don't think that there's anything significant there

server = app.listen(port);
// the configuration hasn't changed
if (configuration === currentConfiguration) {
return;H
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't think that H should be there

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, guess that slipped in but didn't cause an issue

@mamaso
Copy link
Author

mamaso commented May 6, 2016

No problem, I can agree with that!

@drew-gross
Copy link
Contributor

Pinging @davimacedo who is building Parse Server hosting so probably would be using this API extensively.

@gfosco
Copy link
Contributor

gfosco commented May 7, 2016

Looks great! 👍

@davimacedo
Copy link
Member

@drew-gross It's really a great work of @mamaso and for sure it will help Parse Hosting solutions and also future community contributions regarding ideas on parse-community/parse-dashboard#188

My unique suggestion for future contributions is to add more tests: for each setting we could update it and verify the expected behaviors.

help: "Sets the log level"
},
"enableConfigChanges": {
env: "ENABLE_CONFIG_CHANGES",
Copy link
Contributor

Choose a reason for hiding this comment

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

We've been discussing in #1715 what things to expose as env vars, as I think we want to use less env vars in the future. What do you think about making this not be an env var?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, what about defaulting to true? Then the dashboard can just work out of the box without needing to change any config?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or even just removing this setting, and having all settings be editable unless defined in code/cli. The endpoint requires the master key anyway, so it wouldn't be a security issue, and you could always just define everything in code if you want to disable editing even for master key.

Copy link
Author

Choose a reason for hiding this comment

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

Only concern with removing the setting is that enabling config changes adds an extra db call per request. The setting is the way to provide a simple switch to opt out of that penalty.

I'm happy to default to true, whether that's by removing the setting or otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah good point. Lets leave the setting and have it default to enabled then, and also add to the docs that it exists primarily for optimization purposes. Parse philosophy is typically to prioritize better user experience over most other thing, and I think having the dashboard work out of the box for changing settings is better user experience. Also I think given that optimization is the purpose of this setting, we don't need the env var.

Copy link
Author

Choose a reason for hiding this comment

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

Where should I add the documentation on this? Create a wiki page?

@ghost
Copy link

ghost commented May 9, 2016

@mamaso updated the pull request.

@ghost
Copy link

ghost commented May 9, 2016

@mamaso updated the pull request.

@ghost
Copy link

ghost commented May 13, 2016

@mamaso updated the pull request.

logLevel: settings => configureLogger({ level: settings.logLevel }),
verbose: settings => {
settings.logLevel = 'silly';
configureLogger({ level: settings.logLevel });
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this only be done when the setting for verbose is true?

Copy link
Author

Choose a reason for hiding this comment

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

yep, good catch

Copy link
Author

Choose a reason for hiding this comment

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

Not a fan of having both logLevel & verbose settings as the pair leads to weird interactions, but not sure how better to handle it

@ghost
Copy link

ghost commented May 13, 2016

@mamaso updated the pull request.

@drew-gross
Copy link
Contributor

Awesome! Will merge assuming tests pass. Docs can go in the README. Feel free to make that a separate PR.

@mamaso
Copy link
Author

mamaso commented May 13, 2016

Just a heads up, this pr is against the ParsePlatform:settings-endpoint branch so there are likely some merge issues. Want me to point it at master instead?

@drew-gross drew-gross merged commit 993ff20 into parse-community:settings-endpoint May 13, 2016
@drew-gross
Copy link
Contributor

I just merged it. We can do a new PR against master after rebasing.

@faviomob
Copy link

Guys, any progress here? I've deployed Parse Dashboard and still can't see AppSetting tab there =(

@mamaso
Copy link
Author

mamaso commented Aug 10, 2016

Unfortunately my focus has shifted elsewhere and this didn't make it out of the feature branch :/ happy for someone else to pick it up if they like

@mario
Copy link

mario commented Nov 9, 2016

@mamaso what remains to be done, and where's the branch? :)

@Cliffordwh
Copy link

Any news on this?

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.

9 participants