Sunday, March 28, 2021

Glimmer DSL for SWT 4.19.0.0 Halved Startup Time

Glimmer DSL for SWT just had the biggest release in quite a while in version 4.19.0.0:

  • Upgrading to the newly released SWT 4.19
  • Revising scaffolding to generate proper-Ruby-namespaces for Model and View just as done in the recent Tetris sample (instead of just models/views non-namespace directories like Rails does), thus better adhering to the Ruby way of simply relying on require statements in establishing dependencies (distancing itself from the often decried Rails way of autoloading)
  • Supporting `c_combo`, `c_tab_folder`, and `c_tab_item` variations on the `combo`, `tab_folder`, and `tab_item` widgets to permit further customizations to font/background/foreground/height and display of an unlimited number of tabs with a dropdown.
  • Adding two new samples "Hello, C Tab!" and "Hello, C Combo!"
  • Finally addressing the slow startup time of the `glimmer` command, which used to start jruby twice, the first time to determine what options were most appropriate depending on the platform you are on (e.g. Mac requires the -X-JstartOnFirstThread switch) and then running jruby again to start the glimmer app. That ended up wasting a lot of startup time, which fortunately Glimmer packaged (released) apps did not suffer from (they do not rely on the glimmer command given they are native-executable packaged). Also, obviously this was not a truly serious issue given that software engineers could always run glimmer apps directly with jruby anyways, yet just a minor inconvenience. Thankfully, this has been eliminated by relying on JRuby environment variables to set options at gem setup time (it now has a new command `glimmer-setup` for the Mac only where needed), cutting down the glimmer command startup time across the board in half (from about 20 seconds to 10 seconds on an old 2015 MacBook Pro... should be much faster on newer machines)

About the last point, a further thing to note is there are many solutions to reduce the jruby startup time or even eliminate it in Glimmer apps during both development and production. I have been relying on such solutions even if I did not blog about them before, which is what has been keeping me pumping out Glimmer DSL for SWT apps at light speed as everyone would attest by reading my frequent blog posts. 

Please keep in mind first of all that for most business apps, it is not a true issue since users tend to start the app and leave it on all day long, and Glimmer DSL for SWT performance via JRuby is very fast after app startup. Glimmer DSL for SWT productivity, maintainability, and extensibility benefits way outweigh any costs associated with startup time in the enterprise.

That said, in development, it would be useful to reduce the feedback cycle or even eliminate it, and in production, it would be nice to bring up an app instantly if a user uses it often and shuts it down immediately afterwards (still, that is not the common case in the enterprise, which is why I have not given this much attention before).

Regarding development, here are your options:

  • Use Gladiator (Glimmer Editor), which enables you to run any Ruby file instantly (with zero delay) via CMD+R, including Glimmer GUI DSL code. You can see a demo of that on the Gladiator project page (included below).
  • If you prefer another Ruby based Editor/IDE (e.g. Redcar or Arcadia), write a plugin to preload the Glimmer DSL for SWT library (and start with -X-JstartOnFirstThread on the Mac) if needed (should not be needed with Redcar since it runs on SWT too). That way, you should be able to run Glimmer GUI apps instantly as well.
  • Run your code in the included Glimmer Meta-Sample editor, which starts it instantly.
  • Use GIRB (Glimmer IRB), which enables trying out snippets of Glimmer GUI DSL code and seeing app GUI materialize instantly. GIRB is mostly well suited for running small snippets, so it is great for experimentation and learning with the Glimmer GUI DSL.
  • Try passing the `--dev` JRuby option to the `glimmer` command (can accept any jruby option and passes it through), which according to JRuby command documentation, prioritizes startup time over long term performance.


Otherwise, concerning production, you have these options:

  • Build your app as a system tray app (Tray is featured in SWT Widgets). That way, the app stays in the background at all times even if its main window is closed, and can be brought back up instantly.

  • Build your app as a daemon app (aka service or server/client architecture) so that if you close the GUI, the app merely closes the client window while continuing to run in the background. When you start the app again, you have a shell runnable or C executable (can be generated for free with Platypus) that simply alerts the daemon to show its window instantly. The communication mechanism can vary, including DRb (aka druby or distributed ruby run via C Ruby to start fast and connect to the JRuby daemon) or file-based communication (dropping a file somewhere in the user directory). I have tried the DRb approach successfully in the Glimmer Timer sample "glimmer-app-type-client-server" branch
  • Consider Nailgun, which provides similar daemon support to the last idea, but at the JVM level
  • Consider Drip, which spins an extra JVM ahead of time when you start an app and keeps it running for the following run, which starts instantly (I have not tried this yet, but if you try it yourself, please blog about your experience and share here in a comment).
  • Consider showing a Splash Screen to ease startup time on the eyes just like the Eclipse IDE has done for many years. One way to do so is to pass the JRuby "-J-splash" option: -J-splash:./path-to-image/image.png  Another way is to use SWT to render a splash screen until everything in the app is ready to display. This technique is used in Are We There Yet? (Small-Project Tracking App) with gif animation too (albeit for the time being, it's got a minor issue with gif frames sometimes growing beyond its boundaries).
  • Consider contributing to the new Glimmer DSL for Tk early alpha project, which aims to bring Glimmer DSL for SWT niceties to C Ruby (aka MRI) and thus has a much faster startup time than the JVM, albeit keep in mind the trade-offs of Tk like being less enterprise-grade than SWT and requiring Ruby recompilation on every platform, but nothing could stop a highly motivated open-source software engineer from changing that, I'm sure of it.
  • Keep up to date with JRuby innovations for improving startup time; such as details/plans regarding Ahead of Time Compilation, which could theoretically bring startup time to near CRuby levels.
Startup time is most certainly the one trade-off present in Glimmer DSL for SWT that makes app development in it more suitable for the enterprise where users leave apps on all day long. 

To summarize solutions for production app startup time, obfuscate startup time with a splash screen, make startup time instant after the first run with service/client architecture (e.g. DRB) or by trading off extra JVM memory (e.g. Drip), keep tabs on JRuby Ahead of Time Compilation progress, and/or revert to CRuby by using and contributing to Glimmer DSL for Tk.

In any case, here are the new Hello Samples for `c_combo`,  `c_tab_folder`, and `c_tab_item`

Hello, C Combo!






Hello, C Tab!






If you ever have questions concerning Glimmer DSL for SWT, do not make assumptions as it is always a better idea to contact me via Gitter, Blog Comments, or GitHub Issues given my deep experience and expertise with desktop development, JRuby, SWT, and Glimmer/Glimmer DSL for SWT. Also, often I have solutions to problems way far on the horizon, which I have not had a chance to contribute to the codebase yet, but could still share and perhaps even use help contributing in. That would be your chance to become a Glimmer contributor.

Happy Glimmering!

No comments: