Using same configuration schema keys across multiple scripts

This is an issue that took me quite a while to pin down, and longer to consider it a bug, but since the conditions
required to trigger it are somewhat random, I'll try to explain by retelling the story of how I came across it.

Based on the lessons learned in the development of my iTunes script with multiple choice criteria, for some time I've been working on a script for MusicBrainz; one where I'm planning to include cover art size settings.

As a side note, the MusicBrainz database currently only accepts requests for 3 cover sizes (250x250px, 500x500px, 1200x1200px). This will be important for later.

When I got to the development stage of adding a configurations schema to the script, I (being the lazy coded that I am) simply copied an existing .settings file, renamed it to something else, pointed the [Settings] field of the script to the new file and continued development, changing thing as necessary.

In this Settings schema I have dropdown selection box for cover size; with the choices being those referring to the aforementioned ones for MusicBrainz. In the script proper, IfVar commands make the necessary conversion into properly formatted image file links of the selected size.

So far, so good.... or so I thought.

To summarize, at this point I have these conditions:
1 WSS for iTunes (I'll call it WSS.A for simplicity) + its respective .settings file (Settings.A);
1 WSS (in development) for MusicBrainz (WSS.B) + its respective .settings file (Settings.B, but is a modified copy of Setting.A);

Within both Settings.A and Settings.B there is a key, (let's call it Key, for obvious reasons) linked to the cover size dropbox mentioned before.

When running each script, I can then (for example):

  • open Settings.A, set cover size to 600x600px, run WSS.A, which will call Key -set to 600x600- with an IfVar, and have my cover in that size;

and/or

  • open Settings.B, set cover size to 500x500px (as this is one of the sizes recognized by MusicBrainz), run WSS.B, which will call Key -set to 500x500- with an IfVar, and have my cover in that size.

Again, so far so good.... until it wasn't.

At random times, when working on WSS.B, there would be no cover art displayed in the results page. At first, I naturally thought that I'd made a mistake somewhere in the code, do a double-check, fix what was broken (or not), test a couple of sizes to make sure and call it a day.

And then it would happen again. So, rinse and repeat until the bug was tracked down and squashed.


Then one day, while taking a break after working on WSS.B, I wanted to catalog some new music. So I loaded WSS.A (which is the iTunes one, and one that I know is quite stable), searched for the desired album... and there was no cover art.
Checked the settings (cover size was set to 600x600), tried again... nothing. Changed to 1200x1200, and got a cover.
"OK, then. Let's try 600x600 again". And this time got the correct cover image.

Since it's impossible to have 'script contamination', even if I had something broken -or unfinished code- in WSS.B, WSS.A would definitely not be affected.

Several days of this routine (working on WSS.B, getting a cover error, fixing the bug, all OK for a while, then getting a cover error again; and occasionally getting the same cover error on WSS.A) went by.

It took me quite some time to notice a trend, then a relation between these events, and finally a lot of testing to replicate intentionally a seemingly random issue, but eventually I got to the these findings:

Let's have the following scenario:

- open Settings.A, set cover size to 600x600px, run WSS.A -- OK
- open Settings.B, set cover size to 500x500px, run WSS.B -- OK
- run WSS.A again without changing Settings.A -- error

Looking at the debug output of WSS.A, the IfVar that was supposed to trigger when matched to 600x600 in Key did not; despite Settings.A not having been modified between the 2 runs. If I went to Settings.A, the dropbox would still be set to 600x600, but the IfVar would not trigger.

Only by changing to 1200x1200 (or any option other than 600x600), and submitting that change with an 'OK', would the new value now result in a valid cover in the script.

What I eventually learned was that, because both Settings.A and Settings.B share the same Key, Mp3Tag uses the last submitted value of Key in ANY script that calls it, regardless of what .settings file submitted said value.

Running the same scenario as before, now adding the current value of Key:

- open Settings.A, set Key to 600x600px, run WSS.A -- OK (600x600px cover)
- open Settings.B, set Key to 500x500px, run WSS.B -- OK (500x500px cover)
- run WSS.A again without changing Settings.A; 'Key' remains set to "500x500" -- error


As with the previous scenario, even if I went to Settings.A, the dropbox would still be set to 600x600, because it (dropbox selection) hadn't been changed; however in the internal memory of Mp3Tag, Key had been changed to 500x500 via Settings.B.

It's important to note that, in this situation, opening Settings.A, not changing anything, and submitting with 'OK', does not overwrite Key. A change must be made -and submitted- for Key to change.


Let's continue:
- open Settings.A, set Key to 1200x1200px, run WSS.A -- OK (1200x1200px)
- open Settings.A, set Key to 600x600px, run WSS.A -- OK (600x600px)
(some time later...)
- run WSS.B again without changing Settings.B; Key remains set to last value submitted (by Settings.A) -- error

Again, due to the inconsistent and script-wise requirements for this bug to trigger, it was VERY difficult to come up with a theory that fit what I was observing.

If you've managed to follow everything up to this point, congratulations! But by now you're probably thinking:
"All this mess can all be traced back to the OP being lazy. If he replaced Key with Key.A in Settings.A, and Key.B in Settings.B (or not, since now Key.A would be have a different title from Key), then this entire situation could be avoided. There is no bug!"

And you would be completely right! However....
Remember when I said in the beginning that it 'took me quite a while to pin down, and longer to consider it a bug'?

After the bug had been pinned down, I now knew what was happening, and why it was happening, so I put this issue to rest. And then one day, while thinking, I had a disturbing idea.
Consider this hypothetical worst-case scenario:

  • An author 'A' releases a WSS script (WSS.A), with an accompanying Settings.A file; in this file there is a key titled Key;
  • Another author -'B'- releases his WSS script (WSS.B), with the corresponding Settings.B file; in this file, the same key title is used;
    So, unbeknownst to each other, both authors have individually used the same key name (this is possible when using commonplace key names like Key, variable, string, integer, etc.).
  • Mp3Tag user 'X' adds both WSS.A and WSS.B to his installation.

At this point, 'X' now has all the elements required for the bug to manifest, and will be be matter of 'when' (if ever) user 'X' will by 'accident' start the sequence of interactions between WSS/Settings.A and WSS/Settings.B that would trigger the bug (which may not be limited to cover size as I detailed; any Settings variable of any type can cause this issue).

Even if 'X' were to turn to the community for help: 1) it would be extremely difficult to try to describe an issue
that could show up on random intervals, inconsistently, and on possibly any Results' field; and 2) even if 'X' described the issue correctly, the obvious troubleshooting step would be to contact whichever author had their script cause the bug;
and that author, looking at his own script, wouldn't find anything wrong, because in fact, there isn't!

Again, this is a perfect-storm scenario, and may never happen, due to how specific the requirements are.
But the probability is not 0; and this is the reason I'm considering this issue a bug.

If you are a Mp3Tag user and found yourself in this situation, know that you can work around the bug using the steps I described.

If you are a script author, please be mindful when choosing names for your keys.

Thank you for reading.

If I remember correctly I think Florian mentioned this when he introduced the feature.
It does make it possible to share settings in several scripts, but naming is of course an issue. I think maybe adding a unique prefix for your use is sensible.

The only mention I could find regarding this is in the Developing Tag Sources page where it is stated:

Note, that this settings file is used for the user settings of all Tag Sources. The individual objects use the key from the respective settings schema definition.

I completely agree with you, and have considered that. But when choosing said prefix, I would still need to be mindful of others' prefixes when assigning one to myself. For a prefix solution to work properly, a prefix would be assigned to me (and all authors) by a 3rd party who would act a regulatory agent. With this I don't mean necessarily @Florian, as a community moderator -or some other appointed person- would be up to that task.

However, I did think on how I would address this issue. I'm not a coder, so this is merely my opinion, but since .settings file names already must be differently named between each other, as to not cause naming conflicts in file managers, that file name could serve as the prefix you suggested. And (while this would take effort by the developer), with some coding, this prefix system could be applied in Mp3Tag source code, where each schema's keys could be stored internally as prefix[separator]key or settingsfileName[separator]key. When running a script, the [Settings] field would then be used as a filter for the pool of currently stored settings, and only load those that matched. Such cache could be managed by the application, so that on launch, Mp3Tag would compare the stored settings' prefixes against .settings filenames in the folder, and scrub the mismatching ones, thus cleaning out removed scripts/.settings files.

If the sharing of settings between scripts was intended for this feature, can you provide an example case where it would be (more) useful to have one .settings file for more than one script, instead of a 1 script + 1 .settings file pairing system?

I have considered to have a common sets of settings for all my scripts, but I haven’t decided on this.

Anyway I think also there aren’t that many scripts, and even fewer which uses the settings feature, so to be honest I think the most practical solution is to be aware of the issue and adapt when crashes occur.

A common set of settings across multiple scripts is an interesting idea, but please consider the practical experience from my example in the first post: when setting a common field across multiple scripts A and B, both sources A and B must then provide interchangeable values, that don't interfere/generate errors from one to another. This is relatively easy when dealing with multiple scripts for the same source, but not with multiple sources.

As for your second point, the main complication with the example of user "X" I described above would be "how to be aware of the issue" if/when it occurs. Putting myself in the shoes of an regular Mp3Tag user, all I could say would be something along the lines of "script not working; make fix please", on a script suffering from "outside interference".

Maybe this is not a bug, but merely a limitation of the Settings schema feature; but if it's not easily fixable, then the best alternative is to generate topics/documentation for others to be aware of this possibility, and potential steps towards a solution.

I don't think that a general user of Mp3tag would necessarily have to deal with settings interference.

It's easily circumvented if the developers of the WSS use the feature either for sharing settings across multiple scripts by using shared keys for both the settings section and the individual keys. Or prevent any interference by using a dedicated and unique settings section for each of their scripts.

The section on Configuration Schema Definition from the documentation shows an example for a configuration schema, with the key element at the top. The value of this key element serves as a section/namespace identifier for the actual settings file.

If you reuse this key across multiple non-related WSSs, collisions might occur. And if this ever happens with an officially released WSS in the future, at least the three of us now have special awareness of the issues that might occur and how they manifest when using a WSS.

I'm moving this to Web Sources Discussion .

That is the lesson to be taken from this topic. As for me, I've learned it the harder way; and don't to repeat this experience (or have another go through it) any time soon. If sometime in the future that lesson is forgotten, at least now there's one topic addressing it that future me/someone can find.

Minor update to this topic:

For my own sources, I will (eventually) be assigning different keys for different source/settings sets, so that at least internally, the issue is avoided.

But, for when/if the time comes that a 3rd-party source collides with mine (either by accident or -perish the thought- intentionally), the next revision will feature a fail-safe: a Set command placed before the IfVar option will preset the intended [Output] to a "troubleshootable" value, before being changed (again) by the IfVar; so that, if due to a collision, Key has a value outside the intended range of that script, the fail-safe will return 'something' other than a non-descriptive error.

If the day comes where someone posts that, with a cover size setting of 1234x1234, is getting this cover result

imagem

I can save myself plenty of headaches, and from a simple screenshot I can have a have a firm grasp on where to look and what to do to solve that issue.

And I hope that, with this information, I'm able to somehow help in future-proofing WSS scripts for this particular scenario.