' to view further details.",singularKey,name)),!
+ }
+ }
+ }
+}
+
ClassMethod DisplayError(pStatus As %Status)
{
if $$$ISERR(pStatus) {
@@ -2150,7 +2168,6 @@ ClassMethod Load(ByRef pCommandInfo) [ Internal ]
// if the path is to a directory (not a file) and it is not a URL, it must be absolute
$$$ThrowStatus($$$ERROR($$$GeneralError,"The specified path must be absolute."))
}
- set tSynchronous = $$$HasModifier(pCommandInfo,"synchronous")
set tForce = $$$HasModifier(pCommandInfo,"force")
merge tParams = pCommandInfo("data")
// In the case of an update command, pCommandInfo has already been populated in ..Update(). The relevant information was then moved to tParams via the merge command above.
@@ -2200,7 +2217,7 @@ ClassMethod Load(ByRef pCommandInfo) [ Internal ]
set tTargetDirectory = $get(tTargetDirectory, tDirectoryName)
set dotModules = ##class(%File).NormalizeDirectory(".modules", tTargetDirectory)
set tmpRepoMgr = ##class(%IPM.General.TempLocalRepoManager).%New(dotModules, 1)
- set tSC = ##class(%IPM.Utils.Module).LoadNewModule(tTargetDirectory, .tParams, , tSynchronous)
+ set tSC = ##class(%IPM.Utils.Module).LoadNewModule(tTargetDirectory, .tParams)
set tSC = $$$ADDSC(tSC, tmpRepoMgr.CleanUp())
$$$ThrowOnError(tSC)
}
@@ -2249,7 +2266,6 @@ ClassMethod Install(ByRef pCommandInfo) [ Internal ]
set tVersion = $get(pCommandInfo("parameters","version"))
set tKeywords = $$$GetModifier(pCommandInfo,"keywords")
- set tSynchronous = $$$HasModifier(pCommandInfo,"synchronous")
set tForce = $$$HasModifier(pCommandInfo,"force")
set tSearchCriteria = ##class(%IPM.Repo.SearchCriteria).%New()
@@ -2299,7 +2315,7 @@ ClassMethod Install(ByRef pCommandInfo) [ Internal ]
$$$ThrowStatus($$$ERROR($$$GeneralError, "Deployed package '" _ tModuleName _ "' " _ tResult.VersionString _ " not supported on this platform " _ platformVersion _ "."))
}
}
- $$$ThrowOnError(##class(%IPM.Utils.Module).LoadQualifiedReference(tResult, .tParams, , tSynchronous))
+ $$$ThrowOnError(##class(%IPM.Utils.Module).LoadQualifiedReference(tResult, .tParams))
}
} else {
set tPrefix = ""
diff --git a/src/cls/IPM/Repo/Filesystem/Definition.cls b/src/cls/IPM/Repo/Filesystem/Definition.cls
index 49d3b7dc..b99b7d67 100644
--- a/src/cls/IPM/Repo/Filesystem/Definition.cls
+++ b/src/cls/IPM/Repo/Filesystem/Definition.cls
@@ -51,11 +51,7 @@ Method RootSet(%val) As %Status
/// Returns a client to interact with this server.
Method GetPackageService() As %IPM.Repo.IPackageService
{
- set tService = ##class(%IPM.Repo.Filesystem.PackageService).%New(..Root)
- if '$$$IsISCWorker && tService.IsAvailable() {
- $$$ThrowOnError(..BuildCache())
- }
- quit tService
+ return ##class(%IPM.Repo.Filesystem.PackageService).%New(..Root)
}
/// Handles modifiers/data attributes provided from the package manager shell.
@@ -119,7 +115,7 @@ Trigger RootChanged [ Event = UPDATE, Foreach = row/object ]
}
Method BuildCache(
- pPurge As %Boolean = {'$$$IsISCWorker},
+ pPurge As %Boolean = 1,
pVerbose As %Integer = 0,
pAutoDetectDepth As %Boolean = 0) As %Status
{
diff --git a/src/cls/IPM/Storage/Module.cls b/src/cls/IPM/Storage/Module.cls
index aceaf000..d271279c 100644
--- a/src/cls/IPM/Storage/Module.cls
+++ b/src/cls/IPM/Storage/Module.cls
@@ -537,16 +537,7 @@ ClassMethod ExecutePhases(
// Report timing subject to parameter; overall timing if only one phase has yet been tracked in context
// (e.g., set up in multithreaded load) and more than one phase is to be executed.
set tTiming = $get(pParams("Timing"),0)
- set tOverallTiming = tTiming && ($listlength(tPhases) > 1) && ($listlength($get($$$ZPMHandledModules($namespace,pModuleName))) < 2)
-
- // Subscript by namespace to handle application build and integration testing processes, which may
- // load a module in a different namespace (and call ExecutePhases there) at a lower stack level than the
- // initial call to ExecutePhases
- if '$data($$$ZPMHandledModules($namespace)) {
- new $$$ZPMHandledModules
- } else {
- set $$$ZPMHandledModules($namespace,pModuleName) = $get($$$ZPMHandledModules($namespace,pModuleName))_tPhases
- }
+ set tOverallTiming = tTiming && ($listlength(tPhases) > 1)
// Execute resolved phases in sequence
set tLifecycle.PhaseList = tPhases
@@ -806,67 +797,45 @@ ClassMethod HasScope(
quit $listfind(tPhases, scopeItem) > 0
}
-Method LoadDependencies(
- pPhaseList As %List,
- ByRef pParams) As %Status
-{
- set tSC = $$$OK
- try {
- set tVerbose = $get(pParams("Verbose"))
-
- if '$data(pParams("qstruct")) {
- set qstruct = "ck"_$select(tVerbose:"d",1:"-d")
- } else {
- merge qstruct = pParams("qstruct")
- }
-
- // Resolve and validate dependencies
- set tReloadSnapshots = +$get(pParams("UpdateSnapshots"))
- set tPermitDowngrade = +$get(pParams("PermitDowngrade"))
- set tSC = ..BuildDependencyGraph(.tDependencyGraph,,tReloadSnapshots,.qstruct,pPhaseList,,,,,,tPermitDowngrade)
- if $$$ISERR(tSC) {
- quit
- }
-
- if $data(tDependencyGraph) {
- set tOptimizeInstalled = 'tReloadSnapshots
- write:tVerbose !,"Dependencies:"
- set tModuleLoop = ""
- for {
- set tModuleLoop = $order(tDependencyGraph(tModuleLoop),1,tValue)
- quit:tModuleLoop=""
-
- if (tOptimizeInstalled) && '$data($$$ZPMHandledModules($namespace,tModuleLoop)) {
- // Optimize for exact version matches that are already installed.
- if ##class(%IPM.Storage.Module).NameExists(tModuleLoop) {
- set tMod = ##class(%IPM.Storage.Module).NameOpen(tModuleLoop,,.tSC)
- $$$ThrowOnError(tSC)
- if (tMod.VersionString = $listget(tValue,3)) {
- set $list(tValue,2) = ""
- set $list(tDependencyGraph(tModuleLoop),2) = ""
- }
- }
- }
-
- set tServer = $case($listget(tValue,2),"":" (installed)",:" @ "_$listget(tValue,2))
- write:tVerbose !,tModuleLoop," ",$listget(tValue,3),tServer
- }
-
- // Download dependencies.
- kill tParams
- merge tParams("qstruct") = qstruct
- merge tParams = pParams
- set tSC = ##class(%IPM.Utils.Module).LoadDependencies(.tDependencyGraph,.tParams)
- if $$$ISERR(tSC) {
- quit
- }
- }
- } catch e {
- set tSC = e.AsStatus()
- }
- quit tSC
-}
-
+/// Builds a dependency graph for this module, recursively resolving dependencies to the specified depth.
+/// The dependency graph is returned in pDependencyGraph, which is an array where the keys are module names and the values are lists of three items:
+///
+/// - Depth in the dependency tree (1 for direct dependencies, 2 for dependencies of dependencies, etc.)
+/// - Server from which the module will be (or was) obtained; empty string if already installed
+/// - Version string of the module to be installed
+///
+///
+/// If pDepth is 1, only direct dependencies are resolved.
+/// If it is 2, dependencies of dependencies are also resolved, and so on.
+/// If it is 0, dependencies are resolved to any depth.
+///
+/// If pForceSnapshotReload is 1, then any cached snapshot of available modules is reloaded from the repository server(s).
+///
+/// qstruct is passed to the repository manager to control which repositories are queried.
+///
+/// pPhases is a list of lifecycle phases that will be executed for the module.
+/// This is used to determine whether scoped dependencies should be considered.
+/// If empty, all dependencies are considered.
+///
+/// pSubModules is an output parameter that returns a list of submodules that were found.
+///
+/// pPass controls whether exact version dependencies (1) or fuzzy version dependencies (2) are processed.
+/// The method is typically called twice, once for each pass.
+///
+/// pModulePath is used internally to track the path of modules being processed, to detect cyclic dependencies.
+///
+/// If pIgnoreInstalledModules is 1, then already-installed modules are not considered when resolving dependencies.
+///
+/// pKnownDependencies is a list of modules that are known dependencies of the root module being installed.
+/// This is used to avoid considering these modules as already-installed when resolving dependencies.
+///
+/// If pPermitDowngrade is 1, then dependencies that require downgrading an already-installed module are permitted.
+///
+/// If pCheckNestedScoped is 1, then scoped dependencies of dependencies are checked against the phases of the root module being installed.
+///
+/// pSearchList is an output parameter that returns a list of repository servers that were searched.
+///
+/// If pIncludeDisplayName is 1, then the display name of each module is included in the output list for informational purposes.
Method BuildDependencyGraph(
ByRef pDependencyGraph,
pDepth As %Integer = 1,
@@ -881,7 +850,7 @@ Method BuildDependencyGraph(
pPermitDowngrade As %Boolean = 0,
pCheckNestedScoped As %Boolean = 0,
ByRef pSearchList,
- pIncludeDisplayName As %Boolean = 0) As %Status
+ pIncludeDisplayName As %Boolean = 0) As %Status [ Internal ]
{
#define EXACT 1
#define FUZZY 2
@@ -896,10 +865,6 @@ Method BuildDependencyGraph(
set tRepositoryManager = ##class(%IPM.Repo.Manager).%Get(.tSC)
$$$ThrowOnError(tSC)
- // Disregard violation of dependencies of pending modules
- set tInstallContext = ##class(%IPM.General.InstallContext).%Get(.tSC)
- $$$ThrowOnError(tSC)
-
// May want to pass phases to subsequent calls
set tPhases = $case(pCheckNestedScoped, 1: pPhases, : "")
for i=1:1:..Dependencies.Count() {
@@ -949,9 +914,8 @@ Method BuildDependencyGraph(
if 'pIgnoreInstalledModules {
// Also apply requirements presented by other installed modules, with the exception of those that are:
// * Known as dependencies of the root module being installed (and thus eligible for upgrade)
- // * Pending (re)installation
// * Already in the dependency graph
- set tOtherDeps = pKnownDependencies_tInstallContext.GetPendingModuleList()
+ set tOtherDeps = pKnownDependencies
set tExistingDepKey = ""
for {
set tExistingDepKey = $order(pDependencyGraph(tExistingDepKey))
@@ -984,13 +948,6 @@ Method BuildDependencyGraph(
// The "clean" phase can be used to bypass this (by removing modules from the current namespace)
// Forcing an update from disk can also override this, although we ensure that the same module is
// not loaded multiple times in a given operation.
- set tForceSnapshotReload = pForceSnapshotReload
- if tForceSnapshotReload && $data($$$ZPMHandledModules($namespace,tDep.Name),tHandled) {
- if $listfind(tHandled,"Activate") {
- // If we have already activated the given module, don't do so again.
- set tForceSnapshotReload = 0
- }
- }
if ('pIgnoreInstalledModules) && ..NameExists(tDep.Name) {
set tLocalObj = ..NameOpen(tDep.Name,,.tSC)
if $$$ISERR(tSC) {
@@ -998,7 +955,7 @@ Method BuildDependencyGraph(
}
set tInstalledVersionValid = tLocalObj.Version.Satisfies(tSearchExpr) && ((tVersion = "") || (tVersion = tLocalObj.VersionString))
- if tInstalledVersionValid && '(tLocalObj.Version.IsSnapshot() && tForceSnapshotReload) {
+ if tInstalledVersionValid && '(tLocalObj.Version.IsSnapshot() && pForceSnapshotReload) {
set tLocalMod = 1
set tDepth = $select(tPreviousDepth=0:pDepth,tPreviousDepth>pDepth:tPreviousDepth,1:pDepth)
set pDependencyGraph(tDep.Name) = $listbuild(pDepth,"",tLocalObj.VersionString)
@@ -1257,13 +1214,11 @@ ClassMethod GetKnownDependencies(pModuleName As %String) As %List
/// @Argument pReferenceArray Array of all module's resources (including resources that compose a resource) that contain the appropriate phase scope.
/// @Argument pLockedDependencies Whether method should be recursively applied to the module's dependencies (true = yes).
/// @Argument pPhases List of IPM lifecycle phases to be applied to the current module.
-/// @Argument pSkipDependencies Whether to skip loading uninstalled dependency modules.
/// @Argument pDependencyGraph Tree of module's dependencies.
Method GetResolvedReferences(
Output pReferenceArray,
pLockedDependencies As %Boolean = 0,
pPhases As %List = "",
- pSkipDependencies As %Boolean = 0,
ByRef pDependencyGraph) As %Status
{
set tSC = $$$OK
@@ -1275,16 +1230,6 @@ Method GetResolvedReferences(
}
}
- if 'pSkipDependencies {
- kill tParams
- set tParams("Verbose") = 0
- set tParams("qstruct") = "k"
- set tSC = ##class(%IPM.Utils.Module).LoadDependencies(.pDependencyGraph,.tParams)
- if $$$ISERR(tSC) {
- quit
- }
- }
-
set pReferenceArray(..Name, ..Name_".ZPM") = ""
set orderedResourceList = ..GetOrderedResourceList()
@@ -1328,7 +1273,7 @@ Method GetResolvedReferences(
// pLockedDependencies=0 to avoid duplicating effort on nested dependencies;
// this loop will already get all of them.
- set tSC = tModule.GetResolvedReferences(.pReferenceArray,0,,1)
+ set tSC = tModule.GetResolvedReferences(.pReferenceArray,0)
if $$$ISERR(tSC) {
quit
}
@@ -1466,11 +1411,6 @@ Method %OnValidateObject() As %Status [ Private, ServerOnly = 1 ]
quit
}
- // Pre-check for uniqueness among resources (make sure there are no collisions and report descriptive errors if there are).
- // This is simpler than trying to interpret a unique index violation later, and will work in all cases where we're updating modules.
- set tInstallContext = ##class(%IPM.General.InstallContext).%Get(.tSC)
- $$$ThrowOnError(tSC)
-
set tSC = $$$OK
set orderedResourceList = ..GetOrderedResourceList()
set tKey = ""
@@ -1486,10 +1426,6 @@ Method %OnValidateObject() As %Status [ Private, ServerOnly = 1 ]
if $$$ISERR(tSC) {
quit
}
- if tInstallContext.ModuleIsPending(tOtherResource.Module.Name) {
- // %OnAddToSaveSet will correct for this condition.
- continue
- }
if (tResource.Name = tResource.UniqueName) {
// Common case: classes, packages, include files, etc.
set tMsg = $$$FormatText("Resource '%1' is already defined as part of module '%2'; cannot also be listed in module '%3'",tResource.Name,tOtherResource.Module.Name,..Name)
@@ -1549,33 +1485,6 @@ Method %OnAddToSaveSet(
set ..Hash = tHash
set ..LastModifiedTimestamp = $zdatetime($horolog,3)
}
-
- // Deal with resources moving from a module dependent on the current module that hasn't been reloaded yet
- set tInstallContext = ##class(%IPM.General.InstallContext).%Get(.tSC)
- $$$ThrowOnError(tSC)
-
- set tSC = $$$OK
- set orderedResourceList = ..GetOrderedResourceList()
- set tKey = ""
- for {
- set tResource = orderedResourceList.GetNext(.tKey)
- quit:(tKey="")
-
- // If it hasn't been saved yet (to account for module renames)...
- if (tResource.%Id() = "") && (tResource.UniqueName '= "") {
- // ... see if some other resource exists with the same name.
- if ##class(%IPM.Storage.ResourceReference).ResourceNameExists(tResource.UniqueName,.tResourceId) {
- set tOtherResource = ##class(%IPM.Storage.ResourceReference).%OpenId(tResourceId,,.tSC)
- $$$ThrowOnError(tSC)
-
- if tInstallContext.ModuleIsPending(tOtherResource.Module.Name) {
- // Delete the resource. If the pending module still contains it, there will be an error when that module is loaded.
- set tSC = ##class(%IPM.Storage.ResourceReference).%DeleteId(tResourceId)
- $$$ThrowOnError(tSC)
- }
- }
- }
- }
} catch e {
set tSC = e.AsStatus()
}
diff --git a/src/cls/IPM/Utils/Module.cls b/src/cls/IPM/Utils/Module.cls
index a4fa3ab0..d3abef37 100644
--- a/src/cls/IPM/Utils/Module.cls
+++ b/src/cls/IPM/Utils/Module.cls
@@ -20,212 +20,16 @@ ClassMethod CreateAndGetSSLConfig(ByRef pProperties) As %String
return name
}
-/// Format of pDependencyGraph:
-/// pDependencyGraph("module name") = $ListBuild(,,)
-/// pDependencyGraph("module name"," ") =
-ClassMethod LoadDependencies(
- ByRef pDependencyGraph,
- ByRef pParams,
- pWorkQueue As %SYSTEM.WorkMgr)
-{
- // Suspend the error count to avoid spurious messages about errors being detected in load/compile.
- $$$SuspendErrorCount
- set tSC = $$$OK
- set tLocked = 0
- set tRestoreParams = 0
- try {
- set initWorkQueueManager = '$data(pParams("Multicompile","CacheTempIndex"),tCacheTempIndex) || '$isobject($get(pWorkQueue))
- if initWorkQueueManager {
- if '$isobject($get(pWorkQueue)) {
- // There may be one at a higher stack level.
- // Deal with dependencies here, and ensure that previous CacheTempIndex can be restored at the end.
- merge tParamBackup = pParams
- set tRestoreParams = 1
- }
-
- if ($get(pParams("Threads")) = 1) || ($tlevel > 0) {
- set tNumWorkers = -1 // Disable multithreading.
- } else {
- set tNumWorkers = $get(pParams("Threads"),1) // Enable multicompile
- }
-
- set pWorkQueue = ##class(%SYSTEM.WorkMgr).Initialize("/multicompile="_tNumWorkers,.tSC)
- $$$ThrowOnError(tSC)
-
- set tModuleName = ""
- for {
- set tModuleName = $order(pDependencyGraph(tModuleName),1,tData)
- quit:tModuleName=""
-
- // List modules to avoid duplicate loads.
- set pParams("Multicompile","ModuleContext",tModuleName) = $listbuild("Activate")
-
- // Invert dependency graph, subscripts (,)
- set tInvertedDependencyGraph(tModuleName) = $list(tData,2,*)
-
- set tDependentKey = ""
- for {
- set tDependentKey = $order(pDependencyGraph(tModuleName,tDependentKey))
- quit:tDependentKey=""
-
- set tInvertedDependencyGraph($piece(tDependentKey," "),tModuleName) = ""
- }
- }
-
- set tCacheTempIndex = $increment($$$ZPMTempLoadGraphRoot)
- set pParams("Multicompile","CacheTempIndex") = tCacheTempIndex
- kill $$$ZPMTempLoadGraph(tCacheTempIndex)
- merge $$$ZPMTempLoadGraph(tCacheTempIndex) = tInvertedDependencyGraph
- } else {
- lock +$$$ZPMTempLoadGraph(tCacheTempIndex):$$$LockTimeout
- if $test {
- set tLocked = 1
- } else {
- $$$ThrowStatus($$$ERROR($$$GeneralError,"Failed to obtain lock on dependency graph."))
- }
- merge tInvertedDependencyGraph = $$$ZPMTempLoadGraph(tCacheTempIndex)
- }
-
- // Queue load of modules without uninstalled dependencies.
- set tModuleName = ""
- for {
- set tModuleName = $order(tInvertedDependencyGraph(tModuleName),1,tData)
- quit:tModuleName=""
-
- // Check if ALL subnode modules have no server name in the top level node of those modules
- // in the inverted dependency graph (which means they are already installed)
- // ONLY want to check on the initial version of the graph because nodes are killed as modules are installed
- if initWorkQueueManager {
- set tHasUninstalledDependency = 0
- set tSubnode = ""
- while 1 {
- set tSubnode = $order(tInvertedDependencyGraph(tModuleName, tSubnode))
- if (tSubnode = "") {
- quit
- }
- // Check if subnode exists. If it doesn't, then its already been installed because subnodes are killed
- set tSubnodeServerName = $listget($get(tInvertedDependencyGraph(tSubnode)), 1)
- if (tSubnodeServerName '= "") {
- set tHasUninstalledDependency = 1
- quit
- }
- }
- } else {
- set tHasUninstalledDependency = ($data(tInvertedDependencyGraph(tModuleName)) >= 10)
- }
- // If no uninstalled dependencies remain...
- if 'tHasUninstalledDependency {
- set $listbuild(tServerName, tVersion, tDeployed, tPlatformVersion) = tData
- zkill $$$ZPMTempLoadGraph(tCacheTempIndex,tModuleName)
-
- // Missing server name indicates that it's already present locally; nothing to do in that case.
- if (tServerName '= "") {
- if ($tlevel = 0) && ($get(pParams("Multicompile","Verbose"),$get(pParams("Verbose"),0))) {
- write !,"Queuing module load: ",tModuleName," ",tVersion," @ ",tServerName
- }
- set tSC = pWorkQueue.QueueCallback(
- "##class("_$classname()_").LoadModuleReference",
- "##class("_$classname()_").LoadCompleted",
- tServerName, tModuleName, tVersion, $get(tDeployed), $get(tPlatformVersion), .pParams, .pDependencyGraph)
- $$$ThrowOnError(tSC)
- } else {
- // Remove this module from dependencies.
- set tDependentKey = ""
- for {
- set tDependentKey = $order($$$ZPMTempLoadGraph(tCacheTempIndex,tDependentKey))
- quit:tDependentKey=""
-
- kill $$$ZPMTempLoadGraph(tCacheTempIndex,tDependentKey,tModuleName)
- }
- }
- }
- }
- if (tLocked) {
- lock -$$$ZPMTempLoadGraph(tCacheTempIndex)
- set tLocked = 0
- } else {
- // Only call WaitForComplete once (!!!)
- // Recursive calls will do repeat execution of previously-queued jobs.
- set tSC = pWorkQueue.WaitForComplete()
- $$$ThrowOnError(tSC)
- }
-
- merge $$$ZPMHandledModules($namespace) = pParams("Multicompile","ModuleContext")
- } catch e {
- if (e.Name["ZSOAP") {
- set tSC = $get(%objlasterror,e.AsStatus())
- } else {
- set tSC = e.AsStatus()
- }
- }
- if tRestoreParams {
- kill pParams
- merge pParams = tParamBackup
- }
- if (tLocked) {
- lock -$$$ZPMTempLoadGraph(tCacheTempIndex)
- }
- quit tSC
-}
-
-/// Intended to be invoked only as a work queue callback (so %status and %workqueue will be defined)
-/// Signature must match LoadModuleReference per work queue manager conventions.
-ClassMethod LoadCompleted(
- pServerName As %String,
- pModuleName As %String,
- pVersion As %String,
- pDeployed As %String,
- pPlatformVersion As %String,
- ByRef pParams,
- ByRef pDependencyGraph) As %Status
-{
- // Suspend the error count to avoid spurious messages about errors being detected in load/compile.
- $$$SuspendErrorCount
- set tSC = $$$OK
- set tLocked = 0
- try {
- $$$ThrowOnError(%status)
- if $$$ISOK(tSC) && $data(pParams("Multicompile","CacheTempIndex"),tCacheTempIndex) {
- // Remove loaded dependency from dependencies subscript.
- lock +$$$ZPMTempLoadGraph(tCacheTempIndex):$$$LockTimeout
- if $test {
- set tLocked = 1
- } else {
- $$$ThrowStatus($$$ERROR($$$GeneralError,"Failed to obtain lock on dependency graph."))
- }
- set tDependentKey = ""
- for {
- set tDependentKey = $order($$$ZPMTempLoadGraph(tCacheTempIndex,tDependentKey))
- quit:tDependentKey=""
-
- kill $$$ZPMTempLoadGraph(tCacheTempIndex,tDependentKey,pModuleName)
- }
- lock -$$$ZPMTempLoadGraph(tCacheTempIndex)
- set tLocked = 0
-
- // Schedule load of any other modules that may need to be scheduled.
- set tSC = ..LoadDependencies(.pDependencyGraph,.pParams,%workqueue)
- }
- } catch e {
- set tSC = e.AsStatus()
- }
- if (tLocked) {
- lock -$$$ZPMTempLoadGraph(tCacheTempIndex)
- }
- quit tSC
-}
-
ClassMethod LoadQualifiedReference(
pReference As %IPM.Storage.QualifiedModuleInfo,
ByRef pParams,
- ByRef pDependencyGraph,
- pSynchronous As %Boolean = 0) As %Status
+ ByRef pDependencyGraph) As %Status
{
set tSC = $$$OK
try {
#dim tReference As %IPM.Storage.QualifiedModuleInfo
set tReference = pReference.%ConstructClone()
- set tSC = ..LoadModuleReference(tReference.ServerName, tReference.Name, tReference.VersionString, tReference.Deployed, tReference.PlatformVersion, .pParams, .pDependencyGraph, pSynchronous)
+ set tSC = ..LoadModuleReference(tReference.ServerName, tReference.Name, tReference.VersionString, tReference.Deployed, tReference.PlatformVersion, .pParams, .pDependencyGraph)
} catch e {
set tSC = e.AsStatus()
}
@@ -239,14 +43,11 @@ ClassMethod LoadModuleReference(
pDeployed As %Boolean,
pPlatformVersion As %String,
ByRef pParams,
- ByRef pDependencyGraph,
- pSynchronous As %Boolean = 0) As %Status
+ ByRef pDependencyGraph) As %Status
{
// Keep a reference of the singleton in this process (which can be a new process!), so subsequent .%Get() calls return the same instance
set configReference = ##class(%IPM.General.EnvironmentConfig).%Get()
- // Suspend the error count to avoid spurious messages about errors being detected in load/compile.
- $$$SuspendErrorCount
#dim tExpression As %IPM.General.SemanticVersionExpression
set tSC = $$$OK
try {
@@ -263,23 +64,11 @@ ClassMethod LoadModuleReference(
merge qstruct = pParams("qstruct")
}
- // Use % variables that intentionally leak in worker processes, to avoid duplicate work when they go out of scope.
- #dim %installcontext As %IPM.General.InstallContext
- #dim %manager As %IPM.Repo.Manager
- if '$$$IsISCWorker {
- new %installcontext
- new %manager
- }
- set %installcontext = ##class(%IPM.General.InstallContext).%Get(.tSC)
- $$$ThrowOnError(tSC)
- do %installcontext.SetGraph(.pDependencyGraph)
- merge tIndex = pParams("Multicompile","CacheTempIndex")
- do %installcontext.SetCacheTempIndex(.tIndex)
-
- set %manager = $select($isobject($get(%manager)):%manager,1:##class(%IPM.Repo.Manager).%Get(.tSC))
+ #dim manager As %IPM.Repo.Manager
+ set manager = ##class(%IPM.Repo.Manager).%Get(.tSC)
$$$ThrowOnError(tSC)
- set tClient = %manager.CheckServiceCache(pServerName,.tAvailable)
+ set tClient = manager.CheckServiceCache(pServerName,.tAvailable)
if 'tAvailable {
set tSC = $$$ERROR($$$GeneralError,$$$FormatText("Repository '%1' is unavailable.",pServerName))
quit
@@ -309,7 +98,7 @@ ClassMethod LoadModuleReference(
// Ensure requested versions match those required by other modules in the namespace, excluding versions currently being installed
// (the requirements of such modules are already known to be satisfied)
- set tSC = ..GetRequiredVersionExpression(pModuleName,%installcontext.GetPendingModuleList(),.tExpression,.tSourceList)
+ set tSC = ..GetRequiredVersionExpression(pModuleName,,.tExpression,.tSourceList)
if $$$ISERR(tSC) {
quit
}
@@ -330,7 +119,7 @@ ClassMethod LoadModuleReference(
}
set dotModules = ##class(%File).NormalizeDirectory(".modules", tDirectory)
set tmpRepoMgr = ##class(%IPM.General.TempLocalRepoManager).%New(dotModules, 0)
- set tSC = ..LoadModuleFromDirectory(tDirectory,.pParams,tDeveloperMode,pServerName,pSynchronous)
+ set tSC = ..LoadModuleFromDirectory(tDirectory,.pParams,tDeveloperMode,pServerName)
set tSC = $$$ADDSC(tSC, tmpRepoMgr.CleanUp())
} else {
set tAsArchive = -1
@@ -364,7 +153,7 @@ ClassMethod LoadModuleReference(
do tTmpStream.CopyFromAndSave(tPayload)
if (tAsArchive) {
- set tSC = ..LoadModuleFromArchive(tModRef.Name,tModRef.VersionString,tTmpStream,.pParams, pServerName,pSynchronous)
+ set tSC = ..LoadModuleFromArchive(tModRef.Name,tModRef.VersionString,tTmpStream,.pParams, pServerName)
} else {
// Old format (TODO: officially deprecate): try loading a .xml file
@@ -406,8 +195,7 @@ ClassMethod LoadModuleFromArchive(
pModuleVersion As %String,
pArchiveStream As %Stream.Object,
ByRef pParams,
- pRepository As %String = "",
- pSynchronous As %Boolean = 0) As %Status
+ pRepository As %String = "") As %Status
{
set tSC = $$$OK
try {
@@ -438,7 +226,7 @@ ClassMethod LoadModuleFromArchive(
set dotModules = ##class(%File).NormalizeDirectory(".modules", tTargetDirectory)
set tmpRepoMgr = ##class(%IPM.General.TempLocalRepoManager).%New(dotModules, 0)
- set tSC = ..LoadModuleFromDirectory(tTargetDirectory, .pParams, , pRepository,pSynchronous)
+ set tSC = ..LoadModuleFromDirectory(tTargetDirectory, .pParams, , pRepository)
set tSC = $$$ADDSC(tSC, tmpRepoMgr.CleanUp())
if $$$ISERR(tSC) {
quit
@@ -453,8 +241,7 @@ ClassMethod LoadModuleFromDirectory(
pDirectory As %String,
ByRef pParams,
pOverrideDeveloperMode As %Boolean = 0,
- pRepository As %String = "",
- pSynchronous As %Boolean = 0) As %Status
+ pRepository As %String = "") As %Status
{
set tSC = $$$OK
try {
@@ -485,7 +272,7 @@ ClassMethod LoadModuleFromDirectory(
merge tParams("AngularArtifact") = pParams("AngularArtifact")
merge tParams("EnvFiles") = pParams("EnvFiles")
}
- set tSC = ..LoadNewModule(pDirectory,.tParams,pRepository,pSynchronous)
+ set tSC = ..LoadNewModule(pDirectory,.tParams,pRepository)
if $$$ISERR(tSC) {
quit
}
@@ -1243,8 +1030,7 @@ ClassMethod ExportDocumentForObject(
ClassMethod LoadNewModule(
pDirectory As %String,
ByRef pParams,
- pRepository As %String = "",
- pSynchronous As %Boolean = 0) As %Status
+ pRepository As %String = "") As %Status
{
set tSC = $$$OK
set tInitTLevel = $tlevel
@@ -1261,15 +1047,6 @@ ClassMethod LoadNewModule(
}
set commandLineModuleName = $get(params("ModuleName"))
- // Check for valid license key prior to top-level module load
- // This may throw an exception.
- if '$data($$$ZPMHandledModules($namespace)) {
- set tLicenseIsValid = ..CheckLicenseKey()
- if 'tLicenseIsValid {
- write !,"WARNING: Continuing module load without a valid license."
- }
- }
-
// Create a singleton instance for logging of warnings/error messages
set tLogManager = ##class(%IPM.General.LogManager).%Get(.tSC)
$$$ThrowOnError(tSC)
@@ -1336,11 +1113,7 @@ ClassMethod LoadNewModule(
set tDisplayName = $piece(tFirstLoaded, ".", 1, *-1)
set tModuleName = $$$lcase(tDisplayName)
- #dim tInstallContext As %IPM.General.InstallContext
- set tInstallContext = ##class(%IPM.General.InstallContext).%Get(.tSC)
- $$$ThrowOnError(tSC)
-
- if foundNewModuleObj && 'tInstallContext.ModuleIsDependency(tModuleName) {
+ if foundNewModuleObj {
// Check that on an update command with -path flag, the module in the path matches the base module specified for update.
if (commandLineModuleName '= "") && (newModuleObj.Name '= commandLineModuleName) {
set msg = $$$FormatText("The specified path does not contain a module matching the specified module to update. Module in path = %1. Specified module = %2.",newModuleObj.Name,commandLineModuleName)
@@ -1385,32 +1158,10 @@ ClassMethod LoadNewModule(
tstart
}
- if '$data($$$ZPMHandledModules($namespace)) {
- // The purpose of this NEW command is to make sure that the % variable $$$ZPMHandledModules refers to doesn't leak outside this scope.
- // This only happens for the first module to be loaded in a set of dependencies (using zpm "load ..." or zpm "install ...")
- // $$$ZPMHandledModules is also used in the ExecutePhases method of %IPM.Storage.Module to
- // cover cases where new dependencies are added and a module is compiled without reloading, and in the BuildDependencyGraph
- // method to treat installed snapshot versions as installed rather than forcing reload if they have been reloaded
- // as part of the same root module operation.
- new $$$ZPMHandledModules
- set $$$ZPMHandledModules($namespace) = "" //Initialize.
- }
- merge $$$ZPMHandledModules($namespace) = params("Multicompile","ModuleContext")
-
$$$ThrowOnError(##class(%IPM.Storage.Module).CheckSystemRequirements(tModuleName))
- if 'tInstallContext.ModuleIsDependency(tModuleName) {
- if 'pSynchronous {
- // Regular async multi-threaded loading of dependencies
- set tSC = tModule.LoadDependencies("",.params)
- $$$ThrowOnError(tSC)
- } else {
- // Temporary custom loading of dependencies in a synchronous
- // manner to prevent lock timeouts until lifecycle rework
- // is complete (HSIEO-4450)
- do ..SyncLoadDependencies(tModule, .params)
- }
- }
+ kill params("ModuleName") // Ensure module name is not passed down to dependency loads
+ do ..LoadDependencies(tModule, .params)
set tSC = $system.OBJ.Load(pDirectory_"module.xml",$select(tVerbose:"d",1:"-d"),,.tLoadedList)
$$$ThrowOnError(tSC)
@@ -1443,18 +1194,13 @@ ClassMethod LoadNewModule(
quit tSC
}
-/// Temporary workaround to synchronously load dependencies. Can be removed once
-/// HSIEO-4450 is complete.
-ClassMethod SyncLoadDependencies(
+/// Load dependencies of a module in a synchronous manner, one at a time, in the correct order.
+ClassMethod LoadDependencies(
pModule As %IPM.Storage.Module,
ByRef pParams)
{
set isVerbose = $get(pParams("Verbose"),0)
- /*
- * Call to BuildDependencyGraph copied from %IPM.Storage.Module:LoadDependencies
- */
-
set reloadSnapshots = +$get(pParams("UpdateSnapshots"))
set permitDowngrade = +$get(pParams("PermitDowngrade"))
set ignoreInstalled = +$get(pParams("IgnoreInstalled"))
@@ -1463,9 +1209,6 @@ ClassMethod SyncLoadDependencies(
$$$ThrowOnError(sc)
write "Done."
- /* This setting is copied from %IPM.Main:Install */
- set pParams("Install") = 1
-
do ..ConstructInvertedDependencyGraph(.depdendencyGraph, .invertedDependencyGraph)
if isVerbose {
write !, "Created inverted dependency graph from dependency graph"
@@ -1566,7 +1309,7 @@ ClassMethod CheckLicenseKey() As %Boolean
// Limit the number of attempts in case this somehow ends up running in a non-interactive process.
#define MaxTries 5
set tValidLicense = ($system.License.GetKeyStatus() '= "Invalid")
- while ('tValidLicense) && $$$InProgrammerMode && ('$$$IsISCWorker) && ($increment(tTries) <= $$$MaxTries) {
+ while ('tValidLicense) && $$$InProgrammerMode && ($increment(tTries) <= $$$MaxTries) {
write !!,"Your system has no (valid) license key present"
write !,"Copy a valid license key into "_$system.Util.ManagerDirectory()
write !,"and then enter 'y' to activate it. Enter 'n' to continue without a license key, "
diff --git a/src/inc/IPM/Common.inc b/src/inc/IPM/Common.inc
index cadd50bf..2ad75824 100644
--- a/src/inc/IPM/Common.inc
+++ b/src/inc/IPM/Common.inc
@@ -5,9 +5,6 @@ ROUTINE %IPM.Common [Type=INC]
#; Helper for XML import of documents
#define ZPMStudioDocumentModule %IPMStudioDocumentModule
-#; Local % Variable to track modules already handled for a given end goal
-#define ZPMHandledModules %IPMHandledModules
-
#; Local % Variable to indicate that ^Sources update trigger should not be run for modifications to individual resources
#define ZPMDeferModifyResources %IPMDeferModifyResources
@@ -38,8 +35,8 @@ ROUTINE %IPM.Common [Type=INC]
#; Log levels
#define ZPMLogTRACE 0
-#define ZPMLogINFO 1
-#define ZPMLogWARNING 2
+#define ZPMLogINFO 1
+#define ZPMLogWARNING 2
#define ZPMLogERROR 3
#; System method/special variable wrappers
diff --git a/tests/integration_tests/Test/PM/Integration/Update.cls b/tests/integration_tests/Test/PM/Integration/Update.cls
index 7df68f60..513c2a34 100644
--- a/tests/integration_tests/Test/PM/Integration/Update.cls
+++ b/tests/integration_tests/Test/PM/Integration/Update.cls
@@ -46,6 +46,7 @@ Method OnBeforeAllTests() As %Status
Method TestAllNoErrorModulesNoMirror()
{
if $system.Mirror.IsMember() {
+ do $$$AssertSkipped("Skipping test since this is a mirror member")
return
}
// Simple module without dependencies
diff --git a/tests/unit_tests/Test/PM/Unit/CLI.cls b/tests/unit_tests/Test/PM/Unit/CLI.cls
index 2ea8e973..4130f4fc 100644
--- a/tests/unit_tests/Test/PM/Unit/CLI.cls
+++ b/tests/unit_tests/Test/PM/Unit/CLI.cls
@@ -55,9 +55,11 @@ Method TestParser()
set tResults(tCommands)="list-installed"
set tResults(tCommands,"modifiers","tree")=""
- set tCommands($increment(tCommands)) = "install SomeModule"
+ set tCommands($increment(tCommands)) = "install SomeModule -synchronous"
set tResults(tCommands)="install"
set tResults(tCommands,"parameters","module")="SomeModule"
+ set tResults(tCommands,"modifiers","synchronous")=""
+ set tResults(tCommands,"modifiers","synchronous","deprecated")=1
set tCommands($increment(tCommands)) = "install SomeModule 0.0.1-prerelease.42+snapshot"
set tResults(tCommands)="install"