0

Here is the problem:

I have one substantial app that will not run on exist instances with default minimum memory configuration. Now despite this figuring prominently on the installation instructions. User's keep trying to install and consequently crashing their instances. To avoid frustrating users of the app, and to try to maintain a sunshiny attitude beyond and above "RTM!"

Solution (so far)

I modified the pre-install.xql like this to abort if either cacheSize or memory is below required minimum.

xquery version "3.0";

import module namespace xdb = "http://exist-db.org/xquery/xmldb";
import module namespace file = "http://exist-db.org/xquery/file" at "java:org.exist.xquery.modules.file.FileModule";

(: The following external variables are set by the repo:deploy function :)

(: file path pointing to the exist installation directory :)
declare variable $home external;
(: path to the directory containing the unpacked .xar package :)
declare variable $dir external;
(: the target collection into which the app is deployed :)
declare variable $target external;

(: the path to the exist-db installation :)
declare variable $exist_home as xs:string := system:get-exist-home();
(:check available memory:)
declare variable $mem-max := system:get-memory-max();
(: minimum memory requirements :)
declare variable $mem-req := 2000000000;
(: minimum cache Size:)
declare variable $cache-req := 500;

declare function local:mkcol-recursive($collection, $components) {
    if (exists($components)) then
        let $newColl := concat($collection, "/", $components[1])
        return
            (
            xdb:create-collection($collection, $components[1]),
            local:mkcol-recursive($newColl, subsequence($components, 2))
            )
    else
        ()
};

(: Helper function to recursively create a collection hierarchy. :)
declare function local:mkcol($collection, $path) {
    local:mkcol-recursive($collection, tokenize($path, "/"))
};

(: Helper function to check the instance's chacheSize. :)
declare function local:check-cache-size($path as xs:string) as xs:boolean {
    if (file:is-readable($path || "/conf.xml"))
    then
        (
        let $doc := fn:parse-xml(file:read($path || "/conf.xml"))
        return
            if (number(substring-before($doc//exist/db-connection/@cacheSize/string(), "M")) > $cache-req)
            then
                (fn:true())
            else
                (fn:error(fn:QName('https://github.com/duncdrum/cbdb-data', 'err:cache-low'), 'Your configured cacheSize is too low')))
    else
        (fn:true())
};

(: Helper function to check the instance's memory. :)
declare function local:check-mem-size($memory as xs:integer) as xs:boolean {
    if ($memory > $mem-req)
    then
        (fn:true())
    else
        (fn:error(fn:QName('https://github.com/duncdrum/cbdb-data', 'err:memory-low'), 'Your configured -xmx memory is too low'))
};

if (local:check-mem-size($mem-max) and local:check-cache-size($exist_home))
then
    (
    (: store the collection configuration :)
    local:mkcol("/db/system/config", $target),
    xdb:store-files-from-pattern(concat("/db/system/config", $target), $dir, "*.xconf"))
else
    (fn:error(fn:QName('https://github.com/duncdrum/cbdb-data', 'err:pre-crash'), 'An unknown error occured during pre-install'))

The good

The app produces a visible error inside package-manager when expected, User no longer have to wait 20min just to see a generic error and a crashed instances.

The meh

The app is still fully registered to the package-manager, where it can be uninstalled after a partial install. It also appears on the dashboard, although since it aborted it is not functional. App contents are partially written into db/apps/myapp.

Question

Is there a better way to abort (and undo) an install? Provided that installing has to happen via the dashboard's package-manager. I like that users now see custom errors telling them whats wrong, should these be sent to console:log? Must failed installs be cleaned up in post-install.xql, or can I do a better job in pre-install.xql already? Any other obvious oversights in this pre-install.xql.

To test

You can simply create an empty exist app via eXide and replace the default pre-install.xql with the one above. Change the $mem-req to either succeed or error out on your instance. Download app and attempt to install.

Edit 1

According to the docs "[pre-install.xql] will be executed before any package data is uploaded to the database." This is not what I am seeing. Data is uploaded, which is why cleanup is currently required. So this might actually be a bug.

Edit 2

I tried different combinations of util:log or fn:trace which then allow my to call repo-undeploy(), repo-remove() to clean up. But I need fn:error to actually abort to prevent crashing, and to report to package-manager. So yeah feature request seems TWTG. Is there a way to log a message to where error message appear in the package-manager without using fn:error?

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
duncdrum
  • 723
  • 5
  • 13
  • Sounds like a compelling reason for a feature request - to extend the expathrepo code to read minimum memory/storage requirements and prevent installation and provide proper warning/guidance. Or perhaps it should be extended to provide hooks to pre-install to declare that an installation has failed and should be reverted. While the repo code hasn't gotten much love lately, you might propose this to exist-open. If you want to pursue what you can do with the app's own files, I would expect pre-install.xql to be your best hook; post-install.xql won't fire until installation of files is completed. – Joe Wicentowski Jul 16 '17 at 15:42
  • ok I just looked at the expath-repo code and well that might take a while. I still don't quite understand execution order select .xar -> begin install -> execute pre-install ->abort (Is that now a registered install or not? where is it registered) Is there a final trigger for "install succeeded"? Will play with post-install triggers a bit to see if I can hack this to be a little cleaner for the user. – duncdrum Jul 16 '17 at 18:15

0 Answers0