Uploaded image for project: 'Nuxeo Platform'
  1. Nuxeo Platform
  2. NXP-19009

Provide an atomic getOrCreateDocument method

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 8.1
    • Fix Version/s: 9.3
    • Component/s: Core
    • Release Notes Description:
      Hide

      A new method is available in CoreSession: getOrCreateDocument(DocumentModel)
      This method can be used to prevent different threads or Nuxeo instances from trying to create the same document.

      Show
      A new method is available in CoreSession: getOrCreateDocument(DocumentModel) This method can be used to prevent different threads or Nuxeo instances from trying to create the same document.
    • Upgrade notes:
      Hide

      A new method is available in CoreSession: getOrCreateDocument(DocumentModel)

      This method can be used to prevent different threads from trying to create the same document.

      Show
      A new method is available in CoreSession: getOrCreateDocument(DocumentModel) This method can be used to prevent different threads from trying to create the same document.
    • Sprint:
      nxcore 9.1.4, nxcore 9.3.5, nxcore 9.3.6
    • Story Points:
      5

      Description

      The idea is to provide a pattern which to get a document if it already exists or create and get the document of it does not (according to a PathRef for instance), in an atomic cluster-safe manner.

      This will be useful for use case such as:

      • UserWorkspaceRoot creation. Currently with concurrent requests at first access, we can possibly end up with more than one UserWorkspaceRoot. i.e. 2 documents with the same path /default-domain/UserWorkspaceRoot which relentlessly leads to duplicated user workspace for each user
      • Direct results are: 2 different Favorites document, unability to fetch/retrieve existing user collections, etc.

      The pattern will internally need to use transaction management, and cluster-wide locking (through the key/value service compareAndSet, which is atomic).

      The following algorithm will be used:

      1. a lock key is chosen to be unique based on what needs to be created, for instance repository name + parent id + child name — this can be abstracted into a lambda for genericity
      2. set the lock; if locking fails then retry a few times with exponential backoff and on failure return ConcurrentUpdateException
      3. commit transaction + start new transaction
      4. critical section: check if the doc exists; if not, create it — this can be abstracted into a lambda for genericity
      5. commit transaction + start new transaction
      6. remove the lock

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - 0 minutes
                  0m
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 1 week
                  1w