Skip to content

Commit

Permalink
perf: pushPkg endpoint in mod-agreements works unexpectedly slowly
Browse files Browse the repository at this point in the history
Impropve transaction handling in a couple of key areas to facilitate pushPkg functionality -- matches changes made in ingest process and for pushPCI previously

ERM-3455
  • Loading branch information
EthanFreestone committed Nov 28, 2024
1 parent 6359462 commit 2e6b96c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 73 deletions.
128 changes: 68 additions & 60 deletions service/grails-app/services/org/olf/DependentModuleProxyService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,68 +21,76 @@ public class DependentModuleProxyService {
OkapiClient okapiClient

public Org coordinateOrg(String orgName) {

// Simply call the verb method on the client (get, post, put, delete). The client itself should take care of everything else.
// Get and Delete take the uri with optional params map for the query string.
// Post, Put and Patch take in the uri, data that can be converted to json (String or map) and optional params map for the query string.
Org org = Org.findByName(orgName)

if (!org) {
log.debug "No local org for ${orgName}. Check vendors."

def mod_vendor_lookup_result = null;
if ( grailsApplication.config.getProperty('useModVendors', boolean) ) {
// This fetches a max of 2 (we should decide how to handle multiple matches) vendors with an exact name match.
mod_vendor_lookup_result = okapiClient.get("/vendor", [
limit: 2,
query: ('(name=="' + orgName + '")') // CQL
])
}
else {
// Disable mod_vendor lookup
mod_vendor_lookup_result = [ total_records: 0 ]
}

// Resp is a lazy map representation of the JSON returned by the module.
/*
{
"vendors" : [ ... ],
"total_records" : 0,
"first" : 0,
"last" : 0
}
*/

switch (mod_vendor_lookup_result.total_records) {
case 1:
// Exact match
def result = mod_vendor_lookup_result.vendors[0]

org = new Org(
name: result.name,
orgsUuid: result.id,
sourceURI: "/vendor/${result.id}"
).save( flush:true, failOnError:true )
break

case 0:
// No match
// We should add in an option to create vendors if users configure that
if ( grailsApplication.config.getProperty('createMissingVendors', boolean) ) {
throw new RuntimeException("Not yet implemented");
}
Org.withSession { currentSess ->
Org.withTransaction {
Org.withNewSession { newSess ->
Org.withTransaction {
// Simply call the verb method on the client (get, post, put, delete). The client itself should take care of everything else.
// Get and Delete take the uri with optional params map for the query string.
// Post, Put and Patch take in the uri, data that can be converted to json (String or map) and optional params map for the query string.
Org org = Org.findByName(orgName) // This cannot be swapped for executeQuery SELECT -- possibly due to the bindUsingWhenRef

if (!org) {
log.debug "No local org for ${orgName}. Check vendors."

def mod_vendor_lookup_result = null;
if ( grailsApplication.config.getProperty('useModVendors', boolean) ) {
// This fetches a max of 2 (we should decide how to handle multiple matches) vendors with an exact name match.
mod_vendor_lookup_result = okapiClient.get("/vendor", [
limit: 2,
query: ('(name=="' + orgName + '")') // CQL
])
}
else {
// Disable mod_vendor lookup
mod_vendor_lookup_result = [ total_records: 0 ]
}

// Resp is a lazy map representation of the JSON returned by the module.
/*
{
"vendors" : [ ... ],
"total_records" : 0,
"first" : 0,
"last" : 0
}
*/

switch (mod_vendor_lookup_result.total_records) {
case 1:
// Exact match
def result = mod_vendor_lookup_result.vendors[0]

org = new Org(
name: result.name,
orgsUuid: result.id,
sourceURI: "/vendor/${result.id}"
).save( failOnError:true )
break

case 0:
// No match
// We should add in an option to create vendors if users configure that
if ( grailsApplication.config.getProperty('createMissingVendors', boolean) ) {
throw new RuntimeException("Not yet implemented");
}

// Create a new local one.
log.debug "No vendor found. Adding local org for ${orgName}"
org = (new Org(name:orgName)).save(flush:true, failOnError:true)
break

default:
// Multiples.
log.debug "Multiple matches for vendor with name ${orgName}"
// Create a new local one.
log.debug "No vendor found. Adding local org for ${orgName}"
org = (new Org(name:orgName)).save( failOnError:true )
break

default:
// Multiples.
log.debug "Multiple matches for vendor with name ${orgName}"
}
}

return org
}
newSess.clear()
}
}
}

return org
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,26 @@ class PushKBService implements DataBinder {
if (utilityService.checkValidBinding(package_data)) {

// Start a transaction -- method in packageIngestService needs this
Pkg.withNewTransaction { status ->
// Farm out package lookup and creation to a separate method

// These calls mirror what's in upsertPackage but conveniently avoid the
// logic which handles TIPPS
Pkg pkg = packageIngestService.lookupOrCreatePkg(package_data);
// Retain logging information
MDC.put('packageSource', pkg.source.toString())
MDC.put('packageReference', pkg.reference.toString())

// Update identifiers from citation
identifierService.updatePackageIdentifiers(pkg, package_data.identifiers)
Pkg.withSession { currentSess ->
Pkg.withTransaction {
Pkg.withNewSession { newSess ->
Pkg.withTransaction {
// Farm out package lookup and creation to a separate method

// These calls mirror what's in upsertPackage but conveniently avoid the
// logic which handles TIPPS
Pkg pkg = packageIngestService.lookupOrCreatePkg(package_data);
// Retain logging information
MDC.put('packageSource', pkg.source.toString())
MDC.put('packageReference', pkg.reference.toString())

// Update identifiers from citation
identifierService.updatePackageIdentifiers(pkg, package_data.identifiers)
}
newSess.clear()
}
}
}

}
}
result.success = true
Expand Down

0 comments on commit 2e6b96c

Please sign in to comment.