[22:03:12] #startmeeting TechCom RFC discussion [22:03:12] Meeting started Wed Dec 13 22:03:12 2017 UTC and is due to finish in 60 minutes. The chair is DanielK_WMDE. Information about MeetBot at http://wiki.debian.org/MeetBot. [22:03:12] Useful Commands: #action #agreed #help #info #idea #link #topic #startvote. [22:03:12] The meeting name has been set to 'techcom_rfc_discussion' [22:03:27] #topic How to modify all preferences? [22:03:32] #link https://phabricator.wikimedia.org/T178449 [22:03:55] O/ [22:04:04] Hey! [22:04:13] morning all :) [22:04:27] good night [22:04:28] good evening :) [22:05:01] samwilson: so, let me first say I'm sorry about the unclearity regarding this RFC. [22:05:33] DanielK_WMDE: no, it was my fault I'm sure. I wasn't clear enough [22:05:42] we talked about it a bit duringg the techcom meeting, and it seems to me that we should today focus on finding the key questions that need to be anserwerd [22:05:46] the comments you've made today on the patch are great. thanks for that. [22:06:25] yw - but that'S all implementation details. refactoring Preferences into a service is uncrontroversial on an architectural level. [22:06:50] but there are some more fundamental questions about global preferences that should be answered before going ahead. [22:07:04] like - does corre need to iknow abotu some kind of "preference scope" concept? [22:07:18] Krinkle has some thought on that. Krinkle, are you here? [22:07:53] hm, i guess not [22:07:57] Back-reading now [22:08:04] ah :) [22:08:36] So yeah, before we enter the discussion of proposals to solutions or problems, I think we should define a few questions we want to answer first. [22:09:03] The first one, from myself, is about whether we should standardise only a PreferenceStore, or also (separately) a PreferenceRegistry. Let me explain what I mean by that. [22:10:26] * DanielK_WMDE is looking at https://www.mediawiki.org/w/api.php?action=help&modules=options [22:10:31] I don't mean whether we should move the User::preference keys list into a class or not. That in itself is uncontroversial. I mainly want to ask the question of whether or not there would conceivably be multiple registries. E.g. an instance for Global preferences and an instance for local preferences, where the local one would be different on different wikis. This is essentially the case already given different extensions activated on [22:10:31] different wikis. But thus far we have always informally enforced that no preference key can have different meanings on different wikis. [22:11:33] I think that we should stick to that assumption, and ideally enforce it in software [22:11:36] So the question is: Should we (Do we need to) introduce a concept of preference scope? (e.g. "local-enwiki" and "global"). Or is a single registry fine, and thus requires that a preference name means the same across all wikis (which some keys selectively being unavailable on some wikis, due to missing extensions). [22:12:12] personally, i would prefer to not have additional complexities. There is the problem though of perhaps features that exist on one wiki but not another, so on wiki A a pref has options A/B, and on wiki B it has options A/B/C/D. If you have global prefs what do you do when it's set to C but thats not enabled? [22:12:34] (this currently exists with autocomplete search, wikisource has some additional sub-title matching magic) [22:12:44] Krinkle: i think we need such scopes for the per-user values. i don't think we need these scopes for the keys. I'd rather see namespaces for the keys (extension names as prefixes) [22:12:54] the way we've been working is that non-existing prefs are just ignored in global prefs [22:12:55] it should be conceivable that local preferences can have different values, but meanings shouldn't be changed for consistency [22:13:14] samwilson: what does "non-existing" mean, exactly? [22:13:29] e.g. prefs from an extension not installed everywhere [22:13:40] Preferences/PreferencesFactory defines the UI and validation aspects of preferences, correct? and getOption/setOption is just a key/value store [22:14:29] it doesn't seem problematic to me to have keys in the store which are not defined by PreferencesFactory [22:15:00] sure, but how about the case where they key exists but chooses an option thats only available on some wikis? [22:15:05] gadgets are another odd case, because they'll have the same pref key in multiple places, but it might mean a different script [22:15:27] Good point [22:15:32] ebernhardson: then it falls back to the local wiki default [22:15:34] #info gadgets are another odd case, because they'll have the same pref key in multiple places, but it might mean a different script [22:15:48] or rather, the user's setting, and *then* then local default [22:15:51] the caller would need to validate the result of getOption() [22:16:19] So contrary to what I just said, we do have keys that can mean different things. Gadgets. [22:16:20] (and actually, with local-overrides, there's another layer in there) [22:16:28] samwilson: as long as there are local user settings in addition to global that seems plausible [22:16:37] Which is why the current code has a 'global' true/false flag that can opt-out some keys from being global-able. [22:16:41] choosing when to set which would perhaps be difficult/annoying [22:17:03] setting a preference needs some kind of scope mechanism (how would you set global preferences otherwise?), reading shouldn't (too much complexity) - it's up to the service to decide where to get the data from [22:17:05] Validation post-getOption seems undesirable. [22:17:27] having a different local and global service is just a really clumsy way of declaring scope [22:17:31] At the moment, the preference registry is key-based. I don't think we technically support the configuration being different depending on run-time logic. But nothing restricts it. [22:18:02] I'd argue that if it can vary, maybe they should be internally registered as different keys. And then the wiki uses the appropiate key to access the value, based on what is configured to be there. But I can see that ending up rather ugly.. [22:18:41] yeah, one design idea has been to prevent anything outside preferences even having to know it's using a global pref [22:19:08] e.g. runtime decide to register foo-with-x and foo-without-x. But that means when you switch a wiki from x to non-x, preferences with common values seem lost. [22:19:12] if there's scope, does that mean getOption() has to be given that scope? [22:20:32] samwilson: Yes, and no. Regardless of whether the scope is part of the key or not, we may need to support the retrieval method to ask or know about a particular logical store. (e.g. 'local' and 'global'). [22:20:35] what if I want a different global source for the private wikis on my farm then the global ones? or I support both facebook login and google login and those fetch globals prefs from a different source? [22:20:39] That's more about storage then scope, though. [22:21:03] there is no way for all the getOption code to keep up with all the potential complexity a global pref system could have [22:21:19] tgr: that's out of scope so far [22:21:22] setting options is mostly limited to a special page on the other hand [22:21:32] I argued last time around that we should consider having a core concept of global preferences, so that we can have a consistent UI and API for it, but that didn't seem to be well-received [22:21:55] samwilson: for reading options, I can imagine callers being oblivious to scopes. But for updating options... I'm dubious. How would the underlying code decide where which option should be stored? [22:22:00] it's certainly simpler to hide that complexity [22:22:03] We definitely need to also answer the question: With global preferences installed. what is the technical meaning of User::setOption. Does it mean local or global by default? Should it support specifying which store is preferred (based on predefined logical constants, like local/foreign, or maybe local/everywhere?) [22:22:27] "out of scope" for interface design basically means "screw anyone who wants to do it" [22:22:32] DanielK_WMDE: it's done from a separate special page, and can't be done (at the moment) via the API [22:22:48] Specifically, can we hide all the logic related to GlobalPreferences within the PreferenceStore subclass for GlobalPreferences? Or do core methods like User::setOptions and UserOptions API need some awareness. [22:22:50] not implementing it is one thing, defining the interface in a way that prevents it is another [22:22:50] so it's obvious to the user what they're setting, and they can only be setting gobal or local at once [22:22:53] so, default behavior is local only [22:23:46] Krinkle: the main question is IMO, what use cases are there for setOption outside the preferences special page? [22:24:02] samwilson: one note regarding "special page only": please don't put the actual logic into the special page. separate it, so it can be re-used if and when you decide to also provide an api module. [22:24:07] the special page can just be replaced/extended by preferences extensions, that's not a problem [22:24:23] samwilson: having the same thing implemented twice, once for a special page and once for the api, is one of the major headache with the current code base [22:24:24] DanielK_WMDE: oh, yup, it's not; that's just the only user interface for it [22:24:39] gread :) [22:24:50] but if e.g. VisualEditor sets preferences programmatically to remember the last editing mode used, there is no way for the pref extension to interact with that [22:24:52] * great eaven [22:25:13] * DanielK_WMDE can't spell any more and needs to go to bed [22:25:29] TimStarling: I agree. I did suggest something similar on one of the tasks or IRC conversations. I proposed we create a separate interface entirely for GlobalPreferences. Seperate UI as well, given that I foresee that it is going to be very tricky UI-wise to have one interface that differentiates between all the possible interactions to present to the user what their local and global values are and whether to use the local or global [22:25:29] value. [22:25:36] so is something like "I want to add a global/local checkbox in the VE interface" a sane use case? [22:26:36] If we go that route, everything becomes easier. There would be a different API module and Special page, and User remains unmodified. The only change is that GlobalPreferences would hook into getOption to make different values appear. Which may cause some round-trip issues, but we should be able to prevent that if we clean things up a little bit, without too much complexity. But the end result would remain that setting plainly from a [22:26:36] get, can effectively change something. Which might be fine, but maybe not. [22:26:49] couldn't there also be a prefs form field for the VE enablement? but I agree, there could conceivably be prefs that are set but never seen by the user [22:28:07] there are also the userjs-* prefs which are basically a poor man's config store hacked into the prefs system; do we want to support gadgets setting that globally? [22:28:53] samwilson: so, in the global prefs UI, do I also set which preference i want to override locally on this wiki? or how is that decided? [22:28:53] tgr: Regarding VE. Right, I think it's fine to assume default behaviour of all API and User.php interaction to be local-only. But there is also the use case of a feature wanting to promote use of global preferences where possible. [22:29:15] #info Krinkle: If another extension (e.g. VisualEditor) wants a preference to be global by default, how will it do so? [22:29:45] The status quo would be hacks in VisualEditor that conditionally make a request to a different API module, and conditionally call into a different class (GlobalPref instead of User). [22:29:49] Do we want that? [22:30:01] DanielK_WMDE: yes, it's a slightly verbose interface: first, in the global prefs form select a pref for globalisation; then, when viewing that pref in the localprefs form, it's now got a 'override this for this wiki?' checkbox [22:30:10] but it works pretty well. [22:30:39] Or do we want GlobalPrefs to be only interactable with by users from the preferences page when they intentionally decide to make something global. And not allow programmatic user / visual promotion of it within other features. [22:30:51] IMO, have one preference store, support an extra scope paramter for writes, do not support a scope paramter for reads [22:30:51] so it's global opt-in plus local opt-out? fancy... [22:31:20] suggest some common scopes like 'local' and 'global' but otherwise leave it up to the service implementation what to do with the paramter [22:31:22] Krinkle: you said we shouldn't discuss UI too much :) [22:31:29] yup. and just to complicate this discussion perhaps, that local-opt-out is also itself a preference! [22:31:57] (but you can't set it globally, don't worry, we don't try to eat our tails...) [22:32:49] Krinkle: it sounds simpler to limit the places that know about global vs local [22:33:22] samwilson: Right, but that means extensions cannot embrace GlobalPrefs beyond conditional messaging saying "Go here to make it global". [22:33:26] TimStarling: if globalprefs were in core, would that mean scope would be passed when retrieving a pref value? (and it'd default to local) [22:33:54] That is fine I suppose, certainly from a product perspective for MVP. But I'm asking not for product or feature, but about design and whether we're creating something that couldn't adapt to that. [22:33:56] Krinkle: yup. all they can do is say "noglobal". other than that, they get what they're given [22:34:51] samwilson: Right, the current design allows for an extension to allow their pref to become global or not, but it's passive in that by default it remains changes a local one or global one based on that the user decides in the end from the pref page. [22:35:09] IMO supporting scopes on read is bound to end up in horrible UX confusion, with some pieces of code seeing the setting one way and other places another way [22:35:30] "what are my settings on the current wiki" should always be a single well-defined thing [22:35:42] samwilson: if there's a use case for that [22:35:51] samwilson: It sounds like your description of opt-in means a pref key is either always local or always global, and does not allow for a global value with the user overriding it locally on some wikis. Is that right? [22:36:26] If so, we could simplify the design in that get/set would always read/write from the same store based on that opt-in list. [22:36:50] I imagine it would be more useful to have a way to find out where a preference came from after the fact, rather than telling getOption() to get it from a particular place [22:37:10] Krinkle: no, it's opt-out on a per-wiki basis: it goes wiki-default to user-wiki-local to user-global to user-local-override [22:37:19] (or rather, the other direction of those) [22:37:51] it could work the way filerepo works, you know we have wfFindFile() which doesn't let you specify where you fetch a file from [22:37:57] I'm not sure I understand the difference between user-wiki-local and user-local-override [22:38:15] tgr: in my mind, the two things you just said contradict each other. Can you explain? If getOptions doesn't suppoort scopes, how do i tell it to give me the local options, not the effective/merged options? [22:38:16] but underlying that, there are multiple storage objects, one for local and one for global [22:38:32] DanielK_WMDE: why would you want to tell it that? [22:39:02] we need an interface for building the prefs page, sure, but that's a completely separate thing [22:39:05] Krinkle: there's no difference in storage, just in resolution of where the value comes from [22:39:07] and the File class offers lots of hints to the UI about how to present global information [22:39:10] tgr: oh, i thought that's what you meant be "what are my settings on the current wiki". But now I suppose you meant "what are the settings effective on this wiki", right? [22:39:26] it must be informative enough to build a HTMLForm, so it's not just value + scope [22:39:39] DanielK_WMDE: yes [22:39:43] ok [22:40:04] samwilson: are you getting the information you need? What are the questions that block you? [22:41:48] DanielK_WMDE: yes, this is very good. [22:42:06] I think one thing is the separation of the form parts of Preferences... [22:42:59] so one thing we wanted to get out of this was being able to get info about preferences *without* a user context [22:43:01] yea, you said something about two kinds of value objects on the ticket [22:43:11] one PreferenceDescription, and... wwhat else? [22:43:40] yea, well... while I would love to see that separation, I'm not sure it's a requirement/blocker [22:43:48] and another as a simple grouping of those (e.g. pretty much what is currently an HTMLform descriptor [22:44:45] giving extensions a nicer way to define where and how their prefs are shown would be nice. but is it in scope? is it a blocker? [22:44:52] what's theuse case of a user-less preference descriptor? [22:45:00] oh nope, as far as blocking globalprefs, we're fine. I'm going to complete the patch that's there, with full b/c to Preferences, and if there's agreement that there's no need at this moment to support preference-getters knowing about global-vs-local then all is ok I think [22:45:47] samwilson: which patch? there are two, i think... [22:46:10] tgr: I think there's something wanted in the API about not having to have a user when trying to get preferences... there's a ticket for it... [22:46:54] https://gerrit.wikimedia.org/r/#/c/389665 this one. the other will be abandoned (hasn't been yet, as it was an other possibiliity for how to do this whole thing) [22:47:47] tgr: i guess "what preferences are defined on this wiki" is a useful question in some context. but perhaps that need is marginal. [22:48:39] Thank you! [22:48:42] DanielK_WMDE: I'm asking because it's unsafe to assume that all the user's preferences will exist in some non-user-specific context as well [22:48:49] (which might or might not be a problem) [22:49:34] you get all kinds of weirdness, say we are in the middle of a staged rollout and an extension is only enabled for a subset of users [22:49:49] or users can self-define preferences, as with Gadgets 3.0 [22:49:57] yeah, I think it makes sense to be able to get *some* information even about only-user-specific prefs. but that should be easy enough to introduce because it'd only be happening in places where it's apparent what sort of information is wanted [22:50:08] that already causes problems - missing localization messages, etc [22:50:59] (ten minute warning) [22:51:05] there's other wierdnesses too, such as when wiki-default prefs change and how that flows on [22:51:24] but that's reasonably minor I guess, and confusion can be permitted? [22:51:41] IMO splitting off a generic preference description service from the user-specific one can be done later without breaking changes to the interface, so it can be done once there is an actual use case [22:51:48] no strong opinion on it though [22:52:28] tgr: yes, sounds sensible [22:52:49] oh, right, gadgets. even with gadgets 1.0 we have user defined preferences - the ones that enable gadgets. [22:53:07] samwilson: would those be globalizable? [22:53:09] well, those are wiki-defined [22:53:09] yep but we leave them out completely of globalprefs [22:53:16] they probably shouldn't be, until we have global gadgets [22:53:26] the same gadget name can mean different things on different wikis... [22:53:26] they can't be, because the same pref key can mean different things on different wikis [22:53:32] :) [22:53:36] (we have userjs-* preferences but those are not "defined" in any real sense of the word) [22:53:41] (wait - i now realize Krinkle was talking about that earlier) [22:54:06] but with 3.0 you can declare a gadget in your own user namespace AIUI [22:56:33] samwilson: we are nearning the end of the hour, so let me just say... kudos to you for refactoring some nasty old code. I know what you are going through ;) [22:56:59] are there any more things to talk about regarding global preference storage? [22:57:00] hehe thanks :) it's not so bad. thank you to all of you for helping! [22:57:04] any last words? [22:57:14] nope, I reckon we've got a good way forward [22:59:25] wow, silence in the last minutes. [22:59:36] I somehow forgot why the preferences separation is related to this. Why does globalPreferences need to get (or add) preference keys after everything else? Is this for storing the opt-in/opt-out preference key? Which is presumably wiki-local? I suppose those could also be stored in the global table, but I can see why keeping it local to the wiki is attractice (e.g. when deleting a wiki), but also unlikely. [22:59:51] Because a list of all preferences on its own, seems trivial in the current system. [23:00:26] Krinkle: no, it's pretty tricky to get a list of all preferences at the mo, *after* all extensions have added theirs [23:00:29] my understanding is that this needs to happen after all extension hooks that define preferences have been called. [23:00:45] or not tricky, maybe ugly is a better word! [23:01:02] right. so... [23:01:11] #endmeeting [23:01:12] Meeting ended Wed Dec 13 23:01:11 2017 UTC. Information about MeetBot at http://wiki.debian.org/MeetBot . (v 0.1.4) [23:01:12] Minutes: https://tools.wmflabs.org/meetbot/wikimedia-office/2017/wikimedia-office.2017-12-13-22.03.html [23:01:12] Minutes (text): https://tools.wmflabs.org/meetbot/wikimedia-office/2017/wikimedia-office.2017-12-13-22.03.txt [23:01:12] Minutes (wiki): https://tools.wmflabs.org/meetbot/wikimedia-office/2017/wikimedia-office.2017-12-13-22.03.wiki [23:01:14] Log: https://tools.wmflabs.org/meetbot/wikimedia-office/2017/wikimedia-office.2017-12-13-22.03.log.html [23:01:16] thank you all! [23:01:33] thanks DanielK_WMDE