Threads and loops in jira script

Hello, I have a script that runs when a JIRA button is pressed. I wanted to use threads to optimize the script but it gives me problems if I put in the threads the JQLs queries and loops, is there any problem with that? What alternative do we have to use threads?

Thank you very much

Example:

Thread.start{
    def historicalCommitmentSP = []
    resultsSPStartSprint.results.each { result ->
        def issueStartSprint = issueManager.getIssueObject(result.id)
        spStartSprint = (issueStartSprint.getCustomFieldValue(puntosHistoria) ?: 0) as double
}

This is tagged as Jira Cloud but looks like Data Center code, when using threads in Jira you first need to set up some thread locals etc, this can be done with JiraThreadLocalUtils

You’ll also want to set a logged in user to execute the query as, as there won’t be any logged in user by default in a new thread.

Wrapping your code like this should work:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.util.thread.JiraThreadLocalUtils

new Thread(JiraThreadLocalUtils.wrap {
    ComponentAccessor.jiraAuthenticationContext.setLoggedInUser(
        ComponentAccessor.userManager.getUserByName('username')
    )
    
    // Run your JQL here
    
    ComponentAccessor.jiraAuthenticationContext.clearLoggedInUser()
}).start()

If you’re running ScriptRunner 7.11 or above, you could make use of HAPI to simplify, e.g:

import com.atlassian.jira.util.thread.JiraThreadLocalUtils

new Thread(JiraThreadLocalUtils.wrap {
    Users.runAs('username') {
        Issues.search('jql here').each { issue ->
            def customFieldValue = issue.getCustomFieldValue('custom field name')
        }
    }
}).start()

Yes, it is Data Center Code. Thank you very much for your answer. I will try

Hi @rlander , it works in general but with these scriprunner JQLs functions it doesn’t

import com.atlassian.jira.util.thread.JiraThreadLocalUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption


new Thread(JiraThreadLocalUtils.wrap {
    Users.runAs('user') {
        def issueManager = ComponentAccessor.issueManager
        def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

        Issues.search("issueFunction in incompleteInSprint('53343','83300') and issuetype in standardIssueTypes()").each { issue ->
            
            def incompleteIssue = issueManager.getIssueObject(issue.id)
            incompleteIssue.setSummary('test2')
            
            issueManager.updateIssue(user, incompleteIssue, EventDispatchOption.ISSUE_UPDATED, false) 
        }
    }
}).start()

Do you know any method to make these JQLs work with a thread?

Thanks in advance.
Michael Sordo

Michael, the following seems to work for me. Note I’ve changed some of the strings so I can test more easily.

incompleteInSprint and similar ones related to sprints are special cases, as they have a different implementation depending on whether there is an “http context” or not, however, like I said, it seems to work for me.

import com.atlassian.jira.util.thread.JiraThreadLocalUtils

new Thread(JiraThreadLocalUtils.wrap {
    Users.runAs('admin') {
        def issues = Issues.search("issueFunction in incompleteInSprint(\"SSA board\")")

        issues.each { issue ->

            issue.update {
                setSummary('test2')
                setSendEmail(false)
            }
        }
    }
}).start()

cheers, jamie

Hi, @jechlin, thank you for reply. With this example it works, but if we add the slate and the sprint it does not work.

import com.atlassian.jira.util.thread.JiraThreadLocalUtils
 
new Thread(JiraThreadLocalUtils.wrap {
    Users.runAs('admin') {
        def issues = Issues.search("issueFunction in incompleteInSprint('53343','83300')")
 
        issues.each { issue ->
 
            issue.update {
                setSummary('test2')
                setSendEmail(false)
            }
        }
    }
}).start()

Thank you so much
Cheers

Michael Sordo