Page MenuHomePhabricator

Multiple instance forms are parsed once for each template item in a page
Open, Needs TriagePublic

Description

I'm running SemanticForms 3.2, Mediawiki 1.24, SMW 2.1.

Whenever I go to formedit a page that has a large number of 'multiple instance' items, the server response time increases as the number of corresponding templates increase.

Using the form generated by the below schema, a page with 100 DemoTimelineTemplate/Event items takes ~12 seconds for the formedit to load. At 150 DemoTimelineTemplate/Event items, it takes almost 27 seconds to load.

I did a bit of profiling and saw that the majority of the time is spent in recursiveTagParse(); Trying to formedit a page with about 50 items will cause recursiveTagParse() to be called more than 4000 times.

A bit of debugging told me that the for 99% of calls to recurseTagParse() is formFieldHTML() -> getArgumentsForInputCall() -> recursiveTagParse(). The relevant code in SF_FormField.php is:

function getArgumentsForInputCall( $default_args = null ) {

        ....

        foreach ( $other_args as $argname => $argvalue ) {

                if ( is_string( $argvalue ) ) {
                        $other_args[$argname] =
                                $wgParser->recursiveTagParse( $argvalue );
                }
        }
        return $other_args;
}

The values of $argname and $argvalue are only ever the parameters for the multiple instance form's definition, and don't seem to change. It makes me wonder if getArgumentsForInputCall only needs to get called once.

Steps to reproduce:

  1. I'm using the following schema:
<PageSchema>
  <semanticforms_Form name="DemoTimeline">
    <standardInputs freeTextLabel="Free text" inputSummary="1" inputMinorEdit="1" inputWatch="1" inputSave="1" inputPreview="1" inputChanges="1"/>
  </semanticforms_Form>
  <Template name="DemoTimelineTemplate" format="standard">
    <Field name="Title">
      <semanticforms_FormInput>
        <InputType>text</InputType>
      </semanticforms_FormInput>
    </Field>
  </Template>
  <Template name="DemoTimelineTemplate/Event" multiple="multiple" format="standard">
    <semanticforms_TemplateDetails>
      <Label>Events</Label>
      <AddAnotherText>Add event</AddAnotherText>
    </semanticforms_TemplateDetails>
    <semanticinternalobjects_MainProperty name="Has demo timeline event"/>
    <Field name="Type">
      <semanticforms_FormInput>
        <InputType>text</InputType>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="Has demo event type">
        <Type>Text</Type>
      </semanticmediawiki_Property>
    </Field>
    <Field name="Start date">
      <semanticforms_FormInput>
        <InputType>datetime</InputType>
        <Parameter name="mandatory"/>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="Has demo event start date">
        <Type>Date</Type>
      </semanticmediawiki_Property>
    </Field>
    <Field name="End date">
      <semanticforms_FormInput>
        <InputType>datetime</InputType>
        <Parameter name="mandatory"/>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="Has demo event end date">
        <Type>Date</Type>
      </semanticmediawiki_Property>
    </Field>
    <Field name="Summary">
      <semanticforms_FormInput>
        <InputType>text</InputType>
        <Parameter name="mandatory"/>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="Has demo event summary">
        <Type>Text</Type>
      </semanticmediawiki_Property>
    </Field>
    <Field name="Content">
      <semanticforms_FormInput>
        <InputType>textarea</InputType>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="Has demo event content">
        <Type>Text</Type>
      </semanticmediawiki_Property>
    </Field>
  </Template>
</PageSchema>
  1. Create a page with the following content:
{{DemoTimelineTemplate|Title=test}}

followed by 100 lines of this:

{{DemoTimelineTemplate/Event}}
  1. Save the page
  2. Click "edit with form"
  3. CPU on the server spikes, and it takes ~12 seconds for a response to be generated.

Event Timeline

falterx created this task.Mar 13 2015, 9:15 PM
falterx raised the priority of this task from to Needs Triage.
falterx updated the task description. (Show Details)
falterx added a subscriber: falterx.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptMar 13 2015, 9:15 PM

@Yaron_Koren can I add you to task please.

Restricted Application added a subscriber: StudiesWorld. · View Herald TranscriptFeb 14 2016, 2:49 PM
Paladox set Security to None.Feb 14 2016, 2:49 PM
Paladox removed a subscriber: Yaron_Koren.