Skip to content
This repository has been archived by the owner on Nov 9, 2022. It is now read-only.

Slow bootstrap for many users and roles in security DB #738

Closed
ezbc opened this issue Feb 10, 2017 · 5 comments
Closed

Slow bootstrap for many users and roles in security DB #738

ezbc opened this issue Feb 10, 2017 · 5 comments
Assignees
Milestone

Comments

@ezbc
Copy link
Contributor

ezbc commented Feb 10, 2017

Description

Our project is a multi-tenant application with extremely granular security leading to thousands of users and roles in our security database. Bootstrap requests are timing out for our environment with a few thousand roles in the security DB.

To reproduce the problem:

  1. Create many users and roles in the default security DB. See the Xquery script below to create users and roles.
  2. Bootstrap a project with a role configured to be created.

This should lead to a slow execution of the setup:create-roles step in deploy/lib/xquery/setup.xqy.

This is because for each role to be created during the bootstrap, setup:get-roles is called to check if the role-to-be-created exists already. set:get-roles retrieves every role and transforms the elements, an expensive operation for many roles.

A solution I've devised is to retrieve only the role names outside of the role creation FLWOR statement. I will submit a PR soon.

Tech Specs

Windows 10 or Redhat 7.

MarkLogic version 8.0-6

Roxy version 1.7.5-dev

The RFE

Our project currently has enough users and roles where the target server is timing out the bootstrap request. We need to be able to deploy configuration changes to our MarkLogic server.

Script to create users and roles

Run against default security DB.

xquery version "1.0-ml";
import module namespace sec="http://marklogic.com/xdmp/security" at 
    "/MarkLogic/security.xqy";

for $i in 1 to 1000
return
 (
    try {
     xdmp:invoke-function( function() {
       sec:create-role(
        "roxy-test-role-" || $i,
        "load test role",
        ("filesystem-access"),
        (),
        ("testDocument"))
           }, <options xmlns="xdmp:eval">
           <isolation>different-transaction</isolation>
           <transaction-mode>update-auto-commit</transaction-mode>
          </options>
     )
    } catch($e) { ( "ERROR creating user" ) }
   ,
    try {
     xdmp:invoke-function( function() {

         sec:create-user(
          "roxy-test-user-" || $i,
          "load test user",
          "password",
          "roxy-test-role-" || $i,
          (xdmp:permission("security", "read")),
          ("roxy-test-user"))
      }, <options xmlns="xdmp:eval">
          <isolation>different-transaction</isolation>
           <transaction-mode>update-auto-commit</transaction-mode>
        </options>
     )
    } catch($e) { "ERROR creating user"}
 )
@dmcassel
Copy link
Collaborator

@ezbc, your proposed solution sounds good. We'll look forward to the PR.

@RobertSzkutak
Copy link
Contributor

@ezbc Your fix sounds good. Offhand, in your code, I'd recommend getting rid of the try/catch statements unless there's a reason you'd want to continue in spite of an error. They will slow your code down a bit. If you want to keep them, you might as well throw both invokes into the same try/catch which will be a bit more efficient.

@ezbc
Copy link
Contributor Author

ezbc commented Feb 10, 2017

@RobertSzkutak thanks for the tip!

@dmcassel
Copy link
Collaborator

fixed in dev. @ezbc thanks for the PR!

@dmcassel dmcassel added this to the April 2017 milestone Feb 10, 2017
@ezbc
Copy link
Contributor Author

ezbc commented Feb 10, 2017

@dmcassel thanks for the quick review!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants