Topic on Help talk:Extension:ParserFunctions

too many #time calls error

8
Findsky (talkcontribs)

I have a page that uses too much #time, and it ends with an error, can I modify it to increase the number of calls?

Matěj Suchánek (talkcontribs)

No, it's hard-coded: .

RobinHood70 (talkcontribs)

There's always the option of directly altering the extension file itself, though if you do that, you bear the responsibility for any issues it may cause and you'll have to re-make them any time you download an update. If you really need to do that, though, it's just a matter of changing the private const MAX_TIME_CHARS = 6000; near the beginning of the file Matěj Suchánek linked to a higher number.

Verdy p (talkcontribs)

I don't think this constant makes any limit on the number of calls as stated above; it sets a limit on the length of the format string to be parsed. So "#time" is not counted as a "costly parser function call" (like "#ifexist"): it is a memory limit and I think it's reasonnable that a format string should not be arbitrarily long text, its purpose is just to format a datetime value with a few punctuations and short words that may need to be escaped in quotation marks (e.g. "on", "at", "to", "the" and so on in English). So 6000 characters should always be MUCH sufficient for any datetime format string (in almost all common cases, this length does not exist about a dozen characters and extremely frequently it is less than 10 characters!).

Are you sure that the reported error is about "#time" ? As you don't provide any hint about which page is affected (and on which wiki, because this is not this one according to your contribution history here!), we can only guess some hints here about the possible common causes.

Isn't it about too many calls to "#ifexist" (possibly via some transcluded templates where such call cannot be conditionally avoided for wellknown and frequenetly used page names) or an error caused by too expensive Lua expansions (be careful about what you place in infoboxes, and may be there are spurious data in Wikidata, or insufficient filters in the data queries)?

One way to isolate these cases is to edit the page or a section of it, comment out some parts and make a preview (and look at parser statistics displayed at bottom of the preview or in HTML comments at end of the "content" section). If a part generates too much things, then it's a sign that it should go into a separate page or subpage (not to be transcluded from, but linked to).

Other tricks can also be used to reduce the expansion cost, notably if you use templates in long tables with too much inline CSS styles repeatedly: using page stylesheets can help reduce that cost a lot.

Other common cases include too long talk pages, that may need archiving (replace old tals by including a navigation template to the archives, don't transclude too many subpages).

However #time has another limit on the number of locale instances it can load and work with. It is rarely reached but may occur in some multilingual pages using too many locales simultaneously. Most pages shjould limit themselves to use only the default wiki language, or the page's language, or the user's preferred language (or native autonyms only for language names) to avoid breaking that limit.

RobinHood70 (talkcontribs)

If I understood the code correctly, #time is basically implementing its own version of an expensive parser call function, presumably since #time on its own is too cheap to count every single time as expensive. That 6000 characters isn't for a single call; it's the total length of the first parameter for all calls on the page. It's constantly increasing and the only time it's ever reset is on a call to ParserClearState.

Verdy p (talkcontribs)

I've not said that; #time is not an expensive call. But it has limits on the maximum lenth of its parameter for the format string, and a secondary limit on the number of locales it can process from the last optional parameter. It may produce errors, but not to the point of causing a serverside HTTP 500 error: you'll get a red message and a tracking category added to the page when it cannot exceed these limits, but there will still be a default bahavior, the rest of the page should be processed.

As well expensive parser calls (like #ifexist) are counted and even if the limit is reached it does not cause the page not to be processed and the server to reply with an HTTP error 500 without any content displayed. Instead a default behavior is chosen arbitrarily (e.g. #ifexist will operate as if the given page name in parameter was not existing). When template transclusion or parserfunctions expansions cause the maximum page size to be exhausted, there's as well a default behavior: the template is not expanded, instead MediaWiki just displays a visible link with the template page name, the rest is expanded if possible.

However shard limits that cause server side error 500 are memory limits for the expansion of the whole page in some cases, but most of the time it is the time limit (about 10 seconds) which may be reached on pages with too much contents that take too much time to process (especially in Lua modules, e.g. with some infoboxes trying to load too much data from Wikidata). All this has nothing to do with #time.

You did not post any hint abuot which page causes an error for you, so it's impossible to investigate what is the real issue. But I really doubt this is caused by #time: the 6000 character are certianly much enough for the format string, or your wiki page is definitely broken nad has to be fixed (e.g. there were mistched closing braces, or some unclosed "nowiki" section or HTML comment inside the parameters, causing a parameter to be larger than expected.)

RobinHood70 (talkcontribs)

You're misunderstanding what I'm saying completely. Pull out of your current mindset about what's going on here because you've misread both the initial report and my comments, and you're down a path that's completely unrelated to what's going on.

The OP isn't getting a 500 error or a "too many expensive parser functions" error or any other such thing. All they said was that they were getting the error "too many #time calls". That's a defined error in ParserFunctions/i18n/en.json, so we can infer that the error is coming from ParserFunctions, not somewhere else.

Now, re-read the code linked to, above. That error occurs not just when any format text is 6000 characters or greater, it occurs when the total length of the format parameter to all calls exceeds 6000. Notice that the length is accumulating via self::$mTimeChars += strlen( $format );. For whatever reason, that function has been designed to be self-limited in a fashion similar to an expensive parser function, but not actually part of that mechanism.

Verdy p (talkcontribs)

OK this message is misleading, I did not see that there was a "+=" accumulating all calls to #time, and I don't understand at all why this is done. The only useful thing would be to limit the size of the format string itself (and 6000 is even too large for that when this string should prbably never exceed about 256 bytes). If there are other performance issues, the message saying that there are too many "calls" is misleading, and insterad of accumulating lengths, it should use a separate counter (incrementd by 1 for each call, and in that case formatting 6000 dates would seem reasonnable; not if we format the same number of dates to some user languages we get a variable result; it may pass in English, not in Chinese if they need non-ASCII separators or extra characters like the CJK year/month/day symbols). So the implementation (or desiogn choice) is problematic, as well as the message reported.

I don't know why formatting many dates (in the same target language) would be expensive, when we do that for free when formatting numbers. Even if this requires loading locale data, this is one only once and cached for each target language.

With a total of 6000 bytes for all occurences of date format strings, and with each format string taking about a dozen of types for each, sometimes a bit more, this means we can only format about 500 dates on the same page: this is really not a lot, many data tables or talk pages will contain or exceed that number (notably when signature schemes are generated by a template or extension, and not by "tildes" expanded on each saved edit. This will then impact even the ongoing changes needed for talk pages and signatures (depending on how "tildes" are expanded) and will affect many pages showing modest tables with dates (e.g. in articles about sports, history, and so on, possibly generated by data loaded from Wikidata.).

This can as well affect the usabiility of administrative pages showing reports. Making them randomly usable depending on the user language, even though the real cost will be the same (formattiing dats costs much less than parsing any page, or tidying the whitespaces or HTML result, there's even more cost with HTML comments and independation that can fill up large amounts of data in the loaded page, need extra IO on database storage, and extra memory and CPU usage on servers that are much higher than the length of these small format strings; a total of 6000 bytes for all format strings is ridiculously small; it would not even change anything if it was 8KB, and in most cases these short strings are normally interned once they are parsed as parameters, all costs being in the main Mediawiki parser and not in, the #time call itself).

Reply to "too many #time calls error"