From a75b0a441a12e1c62a3e09a66ccf262e2ffea381 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Thu, 12 Mar 2015 17:21:30 -0700 Subject: [PATCH 1/5] Remove dead code from profile.js --- tools/profile.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/profile.js b/tools/profile.js index eb607bfcf4..3fd2fea75d 100644 --- a/tools/profile.js +++ b/tools/profile.js @@ -181,7 +181,6 @@ var running = false; var start = function () { bucketTimes = {}; - currentEntry = []; running = true; }; From e8e7ec43bfd666c8f5bc382d6b9fe380dd93dba2 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Thu, 12 Mar 2015 17:44:46 -0700 Subject: [PATCH 2/5] Add METEOR_PRINT_CONSTRAINT_SOLVER_INPUT env var Very useful for us or users to run! If there's a bug anywhere in the constraint-solver or logic-solver package that comes up when using the tool, we can probably reproduce it just by feeding the JSON that's printed out into the constraint-solver in a test. --- packages/constraint-solver/constraint-solver.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/constraint-solver/constraint-solver.js b/packages/constraint-solver/constraint-solver.js index d03bece734..7f5fc0bc5c 100644 --- a/packages/constraint-solver/constraint-solver.js +++ b/packages/constraint-solver/constraint-solver.js @@ -70,6 +70,12 @@ CS.PackagesResolver.prototype.resolve = function (dependencies, constraints, CS.PackagesResolver._resolveWithInput = function (input, options) { options = options || {}; + if (Meteor.isServer && + process.env['METEOR_PRINT_CONSTRAINT_SOLVER_INPUT']) { + console.log("CONSTRAINT_SOLVER_INPUT = "); + console.log(JSON.stringify(input.toJSONable(), null, 2)); + } + var solver = new CS.Solver(input, { nudge: options.nudge }); From 9b9dfbbf35bdb0e93039e79c4643200120123576 Mon Sep 17 00:00:00 2001 From: Slava Kim Date: Thu, 12 Mar 2015 17:56:25 -0700 Subject: [PATCH 3/5] Kill some dead code in the installer 6K more to go --- .../WixStandardBootstrapperApplication.cpp | 74 ------------------- 1 file changed, 74 deletions(-) diff --git a/scripts/windows/installer/WiXBalExtension/wixstdba/WixStandardBootstrapperApplication.cpp b/scripts/windows/installer/WiXBalExtension/wixstdba/WixStandardBootstrapperApplication.cpp index 449cb7b008..d59f89ef8d 100755 --- a/scripts/windows/installer/WiXBalExtension/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/scripts/windows/installer/WiXBalExtension/wixstdba/WixStandardBootstrapperApplication.cpp @@ -933,80 +933,6 @@ LExit: SetProgressState(hrStatus); } - /* - virtual STDMETHODIMP_(int) OnResolveSource( - __in_z LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in_z LPCWSTR wzLocalSource, - __in_z_opt LPCWSTR wzDownloadSource - ) - { - int nResult = IDERROR; // assume we won't resolve source and that is unexpected. - - LPWSTR sczHTTPDwnUserName = NULL; - LPWSTR sczHTTPDwnPassword = NULL; - LPWSTR sczHTTPDwnHost = NULL; - BOOL bUseHTTPAuth = FALSE; - BOOL bUpdateDwnSrc = FALSE; - - - - if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) - { - if (wzDownloadSource) - { - if (bUseHTTPAuth || bUpdateDwnSrc) - { - HRESULT hr = m_pEngine->SetDownloadSource(wzPackageOrContainerId, wzPayloadId, wzDownloadSource, sczHTTPDwnUserName, sczHTTPDwnPassword); - nResult = SUCCEEDED(hr) ? IDDOWNLOAD : IDERROR; - } - else - nResult = IDDOWNLOAD; - } - else // prompt to change the source location. - { - OPENFILENAMEW ofn = { }; - WCHAR wzFile[MAX_PATH] = { }; - - ::StringCchCopyW(wzFile, countof(wzFile), wzLocalSource); - - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = m_hWnd; - ofn.lpstrFile = wzFile; - ofn.nMaxFile = countof(wzFile); - ofn.lpstrFilter = L"All Files\0*.*\0"; - ofn.nFilterIndex = 1; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - ofn.lpstrTitle = m_pTheme->sczCaption; - - if (::GetOpenFileNameW(&ofn)) - { - HRESULT hr = m_pEngine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, ofn.lpstrFile); - nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR; - } - else - { - nResult = IDCANCEL; - } - } - } - else if (wzDownloadSource) - { - // If doing a non-interactive install and download source is available, let's try downloading the package silently - if (bUseHTTPAuth || bUpdateDwnSrc) - { - HRESULT hr = m_pEngine->SetDownloadSource(wzPackageOrContainerId, wzPayloadId, wzDownloadSource, sczHTTPDwnUserName, sczHTTPDwnPassword); - nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR; - } - else - nResult = IDDOWNLOAD; - } - // else there's nothing more we can do in non-interactive mode - - return CheckCanceled() ? IDCANCEL : nResult; - } - */ - virtual STDMETHODIMP_(int) OnResolveSource( __in_z LPCWSTR wzPackageOrContainerId, __in_z_opt LPCWSTR wzPayloadId, From 83dc85478f892a9eb15b8261f865ee9a4ee6bab6 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Thu, 12 Mar 2015 18:07:20 -0700 Subject: [PATCH 4/5] Add "Select Package Versions" to METEOR_PROFILE There's no detail yet, but I'm going to add some. In the mean time, you just get the total ms for "Selecting Package Versions...", and if it runs a second time you'll get another report for "(Try 2)"! --- tools/project-context.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/project-context.js b/tools/project-context.js index 43b9d60292..8602e2889d 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -14,6 +14,7 @@ var release = require('./release.js'); var tropohouse = require('./tropohouse.js'); var utils = require('./utils.js'); var watch = require('./watch.js'); +var Profile = require('./profile.js').Profile; // The ProjectContext represents all the context associated with an app: // metadata files in the `.meteor` directory, the choice of package versions @@ -407,6 +408,8 @@ _.extend(ProjectContext.prototype, { var anticipatedPrereleases = self._getAnticipatedPrereleases( depsAndConstraints.constraints, cachedVersions); + var resolverRunCount = 0; + // Nothing before this point looked in the official or project catalog! // However, the resolver does, so it gets run in the retry context. catalog.runAndRetryWithRefreshIfHelpful(function (canRetry) { @@ -433,10 +436,18 @@ _.extend(ProjectContext.prototype, { resolveOptions.upgradeIndirectDepPatchVersions = true; } + resolverRunCount++; + + var solution; try { - var solution = resolver.resolve( - depsAndConstraints.deps, depsAndConstraints.constraints, - resolveOptions); + Profile.run( + "Select Package Versions" + + (resolverRunCount > 1 ? (" (Try " + resolverRunCount + ")") : ""), + function () { + solution = resolver.resolve( + depsAndConstraints.deps, depsAndConstraints.constraints, + resolveOptions); + }); } catch (e) { if (!e.constraintSolverError && !e.versionParserError) throw e; From 6b40a2e2bb10e2b4a31557f5471881eaa0028869 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Thu, 12 Mar 2015 18:10:36 -0700 Subject: [PATCH 5/5] Avoid solver error when package mentioned weakly Unloaded packages mentioned in weak dependencies could trigger a situation where the logic solver is asked for the value of a variable that doesn't exist. This issue is worth looking into in more detail, but this is a strict improvement that addresses the basic case. --- packages/constraint-solver/input-tests.js | 17 +++++++++++++++++ packages/constraint-solver/solver.js | 20 +++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/constraint-solver/input-tests.js b/packages/constraint-solver/input-tests.js index 290d060d5a..72d106bf21 100644 --- a/packages/constraint-solver/input-tests.js +++ b/packages/constraint-solver/input-tests.js @@ -718,3 +718,20 @@ Tinytest.add("constraint solver - input - update indirect deps", function (test) } }); }); + +Tinytest.add("constraint solver - input - package is only weak dep", function (test) { + doTest(test, { + dependencies: ["foo"], + constraints: [], + previousSolution: {}, + catalogCache: { + data: { + "foo 1.0.0": ["?bar"] + } + } + }, { + answer: { + foo: "1.0.0" + } + }); +}); diff --git a/packages/constraint-solver/solver.js b/packages/constraint-solver/solver.js index 144b9ead22..83d2e4459a 100644 --- a/packages/constraint-solver/solver.js +++ b/packages/constraint-solver/solver.js @@ -167,7 +167,7 @@ CS.Solver.prototype.analyze = function () { analysis.unknownPackages[p2].push(pvVar(p, v)); } else { if (! dep.isWeak) { - if (analysis.reachablePackages[p2] !== true) { + if (! _.has(analysis.reachablePackages, p2)) { markReachable(p2); } } @@ -551,11 +551,26 @@ CS.Solver.prototype.getSolution = function (options) { }); self.throwAnyErrors(); + var unknownPackages = _.keys(analysis.unknownPackages); + if (unknownPackages.length) { + // XXX make sure we've created variables for these so we don't + // get an error from the solver. there is probably a better + // way to address this. + _.each(unknownPackages, function (p) { + logic.getVarNum(p); + }); + self.solution = logic.solve(); + if (! self.solution) { + // all we did was add new, unconstrained variables + throw new Error("Unexpected unsatisfiability"); + } + } + // try not to use any unknown packages. If the minimum is greater // than 0, we'll throw an error later, after we apply the constraints // and the cost function, so that we can explain the problem to the // user in a convincing way. - self.minimize('unknown_packages', _.keys(analysis.unknownPackages)); + self.minimize('unknown_packages', unknownPackages); // try not to set the conflictVar on any constraint. If the minimum // is greater than 0, we'll throw an error later, after we've run the @@ -689,7 +704,6 @@ CS.Solver.prototype.getSolution = function (options) { // throw errors about unknown packages if (self.stepsByName['unknown_packages'].optimum > 0) { - var unknownPackages = _.keys(analysis.unknownPackages); var unknownPackagesNeeded = _.filter(unknownPackages, function (p) { return self.solution.evaluate(p); });