diff --git a/CHANGELOG.md b/CHANGELOG.md index 27465f59..b21b3c88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `ImportAll` imports items in parallel when `compileOnImport` and `decomposeProductions` are both disabled, reducing import time for large codebases (#970) +- The Incremental Load pull event handler can import and delete items in parallel when `decomposeProductions` is disabled, reducing the time required for various operations (#973) - Import of decomposed production items now has a brief timeout in case another deploy is in progress (#949) - Option to view an individual file's history in the source control menu (#960) - Change context menu now lists IPM packages from all Git-enabled namespaces, prefixed with the namespace name (#952) diff --git a/cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls b/cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls index 3f888277..f72cec2a 100644 --- a/cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls +++ b/cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls @@ -20,6 +20,17 @@ Method OnPull() As %Status } } + // Create a work queue manager to use for importing and deleting items to improve performance + // Currently only used when not using decomposed productions + #dim queue as %SYSTEM.WorkMgr = "" + set settings = ##class(SourceControl.Git.Settings).%New() + if ('settings.decomposeProductions) { + set queue = ##class(%SYSTEM.WorkMgr).%New() + if (queue = "") { + set sc = $$$ADDSC(sc, %objlasterror) + } + } + set nFiles = 0 for i=1:1:$get(..ModifiedFiles){ set internalName = ..ModifiedFiles(i).internalName @@ -45,20 +56,41 @@ Method OnPull() As %Status set ptdList(internalName) = "" } else { set compilelist(internalName) = "" - set sc = $$$ADDSC(sc,##class(SourceControl.Git.Utils).ImportItem(internalName, 1)) + // If a work queue has been created then use it + if (queue '= "") { + set sc = $$$ADDSC(sc, queue.Queue("##class(SourceControl.Git.Utils).ImportItem", internalName, 1)) + } else { + set sc = $$$ADDSC(sc, ##class(SourceControl.Git.Utils).ImportItem(internalName, 1)) + } } } } + // If a work queue was created then wait for all work to finish + if (queue '= "") { + set sc = $$$ADDSC(sc, queue.Sync()) + } + #; First remove production items, then everything else write:$data(delList) !!,"Removing items..." for orderIndex = 1,2 { set item = $order(delList(orderIndex, ""), 1, tExternalName) while (item '= "") { - set delSC = ..RemoveItem(item, tExternalName) + // If a work queue has been created then use it + if (queue '= "") { + set delSC = queue.Queue("..RemoveItem", item, tExternalName) + } else { + set delSC = ..RemoveItem(item, tExternalName) + } set item = $order(delList(orderIndex, item), 1, tExternalName) } } + + // If a work queue was created then wait for all work to finish + if (queue '= "") { + set sc = $$$ADDSC(sc, queue.Sync()) + } + if (nFiles = 0) { write !, "Nothing to Load." quit $$$OK @@ -95,7 +127,7 @@ Method OnPull() As %Status quit sc } -Method RemoveItem(pInternalName, pExternalName) As %Status +ClassMethod RemoveItem(pInternalName, pExternalName) As %Status { #Dim delSC As %Status set delSC = ..DeleteFile(pInternalName, pExternalName) @@ -108,7 +140,7 @@ Method RemoveItem(pInternalName, pExternalName) As %Status quit delSC } -Method DeleteFile(item As %String = "", externalName As %String = "") As %Status +ClassMethod DeleteFile(item As %String = "", externalName As %String = "") As %Status { #Dim sc As %Status = $$$OK #Dim err As %Exception.AbstractException