When I describe InterSystems IRIS, I always start with how it is a multimodel DBMS at its core.

In my opinion that is its main advantage (on the DBMS side). And the data is stored only once. You just choose the access API you want to use.

  • You want some sort of summary for your data? Use SQL!
  • Do you want to work extensively with one record? Use objects!
  • Want to access or set one value and you know the key? Use globals!

More about multi-model approach of InterSystems IRIS.

But InterSystems IRIS is not only a DBMS, there are a lot of features, including:

  • Application engine
  • Integration engine
  • BI and NLP analytics, reports
  • AI and ML

I'd mimic %DispatchSetMultidimProperty signature. Shame local cannot be casted into a multi-argument call. Wrap in $g if values can be skipped.

/// do ##class().Test()
ClassMethod Test()
{
    kill ^data
    do ..setValue("val", "key1")
    do ..setValue("val", "key1", "key2", "key3", "key4")
    zw ^data
}

ClassMethod setValue(val, args...)
{
    if args=1 {
        set ^data(args(1)) = val
    } elseif args=2 {
        set ^data(args(1), args(2)) = val
    } elseif args=3 {
        set ^data(args(1), args(2), args(3)) = val
    } elseif args=4 {
        set ^data(args(1), args(2), args(3), args(4)) = val
    }
}

Terminal works under your OS user, BPL works under InterSystems user (typically irisusr).

This type of error is often caused by:

  1. IRIS OS user does not have permissions to access the input and/or output file
  2. IRIS OS user does not have required executables in PATH
  3. IRIS OS user does not have required shared libraries in LD_LIBRARY_PATH

To solve issue (1) create input and output files in IRIS Temp directory - a path returned by:

write ##class(%File).NormalizeDirectory(##class(%SYS.System).TempDirectory())

To test for issues (2) and (3) add a $zf call which inits all your dependencies and returns version or some other trivia.

To adjust PATH and LD_LIBRARY_PATH use System Management Portal. Here's some info.

I recommend checking environment variables from inside your process with:

write $SYSTEM.Util.GetEnviron(Name)

For quick testing you can adjust environment variables for the current process with this community utiliy.

Here's the code to get capitalized piece of string by number:

/// Get Capitalized piece.
///   str - string to search
///   piece - 1-based piece to return
/// write ##class(test.CustomQuery).GetCapitalizedPiece()
ClassMethod GetCapitalizedPiece(str As %String = "lowerHelloWorldAgainHelloWorldAgainHelloWorldAgainHelloWorldAgain", piece As %Integer = 1) As %String
{
    
    // Only uppercase letters
    set upper = $tr(str, $zcvt(str, "l"))
    
    // Number of uppercase letteres
    set capCount = $l(upper)
    
    // Quit if requested piece can not exist
    quit:piece>capCount ""
    quit:piece<1 ""
    
    // First letter in our capitalized piece
    set startLetter = $e(upper, piece)
    
    // All previous capitalized letters
    set prevLetters = $e(upper, 1, piece - 1)

    // Check if current capitalized letter is a first capitalized letter
    // If not - skip previous capitalized letters
    if '$find(prevLetters, startLetter) {
        set start = $find(str, startLetter) - 1
    } else {
        set count = $l(prevLetters, startLetter) + 1
        set start = 0
        while $i(count,-1) {
            set start = $find(str, startLetter, start)
        }
        set start = start - 1
    }
    
    // Is this capitalized piece the last one?
    if piece=capCount {
        set end = $l(str)
    } else {
        set end = $find(str, $e(upper, piece + 1), start) - 2
    }

    quit $e(str, start, end)
}

Advantages over regexp:

  • ~50 times faster
  • Get any piece, not only the second one (although generating required regexp by piece number seems easy to do)

4 years later I can safely say that Poolsize can exceed the number of CPU Cores.

The main exception is when a job consumes the entire CPU core. Usually a process mostly waits for network, disk io or some other io or whatever. In that case it's perfectly fine for Poolsize to exceed available CPU Cores - let them wait together. On the other hand if a process consumes a CPU core entirely - in that case Poolsize exceeding CPU cores count won't help.

In general increasing Poolsize overly much can lead to overconsumption of CPU or disk or other resources, which depending on resource concurrency model may (and often does) negatively impact overall performance.

To @alex chang I can recommend monitoring queues count, sql queries, system metrics and cpu/ram/hdd consumption - clearly there's a bottleneck somewhere.

Additionally while Visual Trace is a great tool it does not show everything a process does - only messages sent and received. Is there anything a process does between receiving a request and calling another process?

Finally Monlbl can be used to check which part of the generated BPL code takes a lot of time.

Here's how you can create a REST API and call production from it.

Inside your REST handler you can access request body via:

  • %request.Data - get access to request body as one binary or character stream
  • %request.GetMimeData("MimeDataName") - get access to request form data value as binary or character stream

Here's a simple fileserver in ObjectScript.

In Docker it's as easy as

ENV GWDIR /jgw
ENV ISC_PACKAGE_INSTALLDIR /usr/irissys
ENV ISC_JARDIR $ISC_PACKAGE_INSTALLDIR/dev/java/lib/JDK18

COPY --from=store/intersystems/iris-community:2020.2.0.211.0 \
     $ISC_JARDIR/intersystems-gateway-3.1.0.jar \
     $ISC_JARDIR/intersystems-jdbc-3.1.0.jar \
     $ISC_JARDIR/intersystems-utils-3.1.0.jar \
     $ISC_PACKAGE_INSTALLDIR/dev/java/lib/gson/gson-2.8.5.jar \
     $GWDIR/

You can check this article for more details.