Skip to content
All posts
3 min readtebakopackagingtutorial

Advanced payloads: packed-mn: one download, any document (5 of 5)

The advanced payloads series: packed-mn: one download, any document.

The Tebako team

github.com/tamatebako
Note

Post 5 of 5 in the series Advanced payloads.

○ ○ ○ ○ ●

The last subject in the series is the whole stack at once: packed-mn, the single-executable Metanorma distribution — a Ruby application that drives a JVM, mounts Inkscape, and uses a declared Python tool from the host. Every concept from all three series appears in this one package.

Ruby calls Java calls Python your packaged Ruby process metanorma compile Java — a spawned runtime the JVM exe + its env image are materialized and started under the same mounts Inkscape — a mounted payload one .tfs image mounted at /opt/inkscape, its files read through the VFS like local ones Python — a host tool the honest route: declared in the manifest as a need, used from the host, visible in the trace three mechanisms, one rule: everything the process uses is declared

Figure 1 — Three routes out of one packaged process: a spawned runtime, a mounted payload, and a declared host tool.

The compile

The following command compiles an OIML Recommendation written in Metanorma and outputs all four kinds of format:

$ metanorma compile sources/r060/1/document.adoc
# → document.xml  (191 KB)   the semantic XML
# → document.html (225 KB)   the HTML rendering
# → document.rxl  (11 KB)    the Relaton bibliographic extract
# → document.pdf  (751 KB)   the print-ready PDF

How it maps

The packed-mn executable is one tebako package; the table maps every piece of it to the tebako part it is and to where the piece lives at run time:

What the user meets Which tebako part it is Where it lives

The executable the user downloads

The bootstrap, the stitched payload slots, and the trailer

One file — that is the whole download

Metanorma 1.16.9, with its 260 gems

Payload slice 1.16.9-8

Stitched into a slot inside the executable

Ruby 3.3

The runtime 0.16.21, named in the trailer

Downloaded once to ~/.tebako, verified, shared by every package

OpenJDK 21 (Temurin 21.0.12), for mn2pdf and jing

Spawned runtime 2.1.5

Resolved from the registry into the store on first use

Inkscape, for figure rasterization

A mounted payload slice, declared as a dependency

Mounted at /opt/inkscape at run time

xml2rfc, for the IETF flavors

A declared host tool — used only if the host machine provides it

The host machine, stated openly in the manifest

The manifest that declares it is the requires: grammar from the architecture series; the JVM arrives by the spawned-runtime route, and Inkscape by the mounted-payload route, exactly as drawn above.

The numbers

The v2 composition is compared against the one-file executable it replaces, on the compile above:

warm workload (n=5, median wall) packed-mn v1.16.9 exe tebako v2 managed + shim v2 vs v1

compile document.adoc -x html

51.9 s

52.5 s

1.01×

compile document.adoc -x pdf

61.0 s

67.1 s

1.10×

metanorma version boot

4.70 s

4.06 s

0.86×

Peak RSS decreases on every row: html 1.38 → 1.22 GiB, pdf 1.35 → 1.29 GiB, boot 0.99 → 0.76 GiB.

cold (fresh store, single run) packed-mn v1.16.9 exe tebako v2 managed

html compile

119.1 s

88.0 s

pdf compile

145.4 s

98.0 s

first metanorma version

(runtime baked at install)

57.2 s

The measurements used a MacBookPro18,2 (Apple M1 Max, 64 GB, macOS 14.1.1), measured while idle; the document is mn-samples-oiml’s OIML r060 (ba74c74), and outputs were verified as regenerated in every cell.

Where the three series end

The architecture series explains the model, the basics reproduce it step by step, and this post has pushed the same model through its most demanding workload. Builders of equally demanding payloads are invited to report the experience in the issue tracker.

Note

This is the end of the series Advanced payloads — and of the tutorial. The how-to guides cover every command in depth.