Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-57642

Improving the performance on Adding Team Calendar Macro into Page

    XMLWordPrintable

Details

    Description

      Problem

      Adding new Calendar in Page using Team Calendar Macro might fail if the user belongs to too many groups and the space has a lot of calendars within itself.
      The macro will search for all group memberships and eventually hit the threshold that is set and the warning message below is thrown in the log:

       [http-nio-8081-exec-4] [confluence.util.profiling.DefaultActivityMonitor] close Exceeded the threshold of 60000 ms
       

      This threshold is not able to be extended due to the block at CONFSERVER-36883

      When creating a new calendar through the Team Calendar Macro, Confluence do a bunch of permission checks for each of the existing subcalendars within the space. The server returns a complete object with all of the sub calendars within the space which is necessary for processing on the front-end. This can be seen below ("AbstractSubCalendarResource#toExtendedSubCalendar), this is performed when the user clicks "Add new Calendar"

      private SubCalendarsResponseEntity.ExtendedSubCalendar toExtendedSubCalendar(PersistedSubCalendar subCalendar, ConfluenceUser forUser)
       {
       UtilTimerStack.push("CalendarResource.toExtendedSubCalendar()");
       try
       {
       return new SubCalendarsResponseEntity.ExtendedSubCalendar(
       subCalendar,
       calendarPermissionManager.hasViewEventPrivilege(subCalendar, forUser),
       calendarPermissionManager.hasReloadEventsPrivilege(subCalendar, forUser),
       calendarPermissionManager.hasEditSubCalendarPrivilege(forUser),
       calendarPermissionManager.hasEditEventPrivilege(subCalendar, forUser),
       false,
       false,
       false,
       calendarManager.isEventsOfSubCalendarHidden(subCalendar, forUser),
       calendarPermissionManager.hasDeleteSubCalendarPrivilege(subCalendar, forUser),
       calendarPermissionManager.hasAdminSubCalendarPrivilege(subCalendar, forUser),
       new HashSet<SubCalendarsResponseEntity.ExtendedSubCalendar.PermittedUser>(
       Collections2.transform(
       calendarPermissionManager.getEventViewUserRestrictions(subCalendar),
       new UserToPermittedUserTransformer(userAccessor, settingsManager)
       )
       ),
       calendarPermissionManager.getEventViewGroupRestrictions(subCalendar),
       new HashSet<SubCalendarsResponseEntity.ExtendedSubCalendar.PermittedUser>(
       Collections2.transform(
       calendarPermissionManager.getEventEditUserRestrictions(subCalendar),
       new UserToPermittedUserTransformer(userAccessor, settingsManager)
       )
       ),
       calendarPermissionManager.getEventEditGroupRestrictions(subCalendar),
      // getSubCalendarWarnings(subCalendar),
       new HashSet<String>(),
       false //reminder
       );
       }
      

      Within a few of these "hasPrivilege" methods, if the user is not the creator of the subcalendar, Confluence check Admin group membership for the user isUserMemberOfOneGroup(user, CONFLUENCE_ADMINISTRATORS_GROUP_NAMES) which gets all of the user's groups and checks if the Admin group is contained within that list. This uses the method

      "DefaultUserAccessor#getGroupNames", which calls the following method to performs the permissions check:

      public List<String> getGroupNamesForUserName(String userName) {
       return (List)(userName == null ? Collections.emptyList() : ImmutableList.copyOf(this.crowdService.search(QueryBuilder.queryFor(String.class, EntityDescriptor.group()).parentsOf(EntityDescriptor.user()).withName(userName).returningAtMost(-1))));
       }
      

      So in summary, for every subcalendar, Confluence may have to retrieve all of the groups that the user belongs to multiple times.

      Suggestion

      Since it will be retrieving the same groups every time, we should be able to improve the performance by adding some simple caching.

      Workaround

      1. Add a new Calendar from My Calendar View and link it to the desire space
        • This method can still allow user to create calendar without hitting the issue above
      2. Search and insert the calendar in a space that has no calendar (in order to avoid this issue) and examine the Storage Format to get the calendar macro that look like below:
         <ac:structured-macro ac:macro-id="f1360258-9d29-4828-b510-ba63bdfc51e3" ac:name="calendar" ac:schema-version="1">
            <ac:parameter ac:name="id">859956f5-0eb8-4169-9c5b-24a034e40578</ac:parameter>
          </ac:structured-macro>
        
      3. From the storage format above, either copy it and add it into the affected page using Source Editor or type the wiki markup like below to insert the calendar macro:
        {calendar:id=859956f5-0eb8-4169-9c5b-24a034e40578}
        

      Attachments

        Issue Links

          Activity

            People

              aknight@atlassian.com Alex K
              btan@atlassian.com Damien Tan
              Votes:
              4 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: