Application Mode
When launching Deephaven, you may want to initialize the server state before any client can connect to the server. Application Mode enables users to bind tables, plots, functions, etc. to REPL variables, and read-only accessors, available during the runtime of the server process.
The variables, tables, functions, etc. that are exposed in the application are then available on the dashboard. For example, you can create scripts to instantiate helper functions to use inside the IDE. Or, you can even develop scripts for full dashboards. Application Mode allows this work to be more readily shared.
This guide will show you how to use Application Mode and what feature set it offers.
Application types
There are many different applications that you can run, from a Python or Groovy script designed to run in Deephaven, to a Dynamic application written in any JVM-based language.
- Script Application: Configure an application in the context of the script type of the Deephaven server.
- Static Application: Configure an application that declares all exported variables during server initialization.
- Dynamic Application: Configure an application that may change what variables are exported based on state changes throughout the life of the application.
- QST Application: Configure an application from a persisted model of a QST. (Coming Soon!)
Runtime JVM Flags
The following flags are available for configuration:
-Ddeephaven.application.dir=/path/to/application/root
- The Deephaven server loads all files that match*.app
in alphabetical order from the given directory during initialization before it begins to listen for requests to serve connecting clients (including Deephaven’s web user interface). This parameter is not set by default.-Ddeephaven.console.type=$SCRIPT_LANGUAGE_TYPE
- Specifies which language type the Deephaven server will use for Application Mode and console REPL sessions if applicable. The default ispython
.-Ddeephaven.console.disable=$BOOLEAN
- Some applications may wish to prevent API clients, including Deephaven’s web client, from starting REPL sessions. Beware that REPL sessions give users the same privileges on the host machine as the user executing the process. The default isfalse
.
When using Deephaven’s Docker setup, API clients will not be able to access anything that is not directly exposed by the docker-compose
configuration. The Docker environment configurations .env
(picked up by default) and default-groovy.env
set these flags on your behalf.
At this time, the Deephaven server can only support a single script type per instance. If you attempt to load the wrong type of script application, then the server will fail-fast to aid in debugging the misconfiguration. See deephaven-core#1172 for more details.
Syntax
Deephaven expects the following fields to be in an *.app
file:
type
- Recommended to help organize the scripts you'll run; e.g,static
,script
,qst
,dynamic
.scriptType
- Useful to describe the proper environment for scripts; e.g.,groovy
orpython
.enabled
- Set totrue
orfalse
to run or skip the scripts in the application file. The default istrue
.id
- An identifier only exposed to API clients; enablingname
changes without requiring layouts to be regenerated.name
- A description that is displayed to users when mentioning this application.file_
- Pathway to each script to run. These are executed in numerical order (after removing the prefixfile_
), not in the order listed in the application. This feature can be used to initialize commonly used values across disparate Applications.
Example *.app file
This is an example .app
file with the fields listed.
type=script
scriptType=groovy
enabled=true
id=hello.world
name=Hello World!
file_0=helloWorld.groovy
Script Application example
In this example, we seed the files needed to use Application Mode, start the Deephaven server, and then see the results in the console.
By default, all Deephaven deployments mount ./data
in the local deployment directory to /data
in the running Deephaven containers. See our guide on Docker data volumes for more information.
Create an app.d
folder inside your ./data
directory:
mkdir data/app.d
The app.d
folder is parsed for all files with an .app
extension and executes each individually in alphabetical order.
As an example .app
file, create the file firstApp.app
with the following contents.
type=script
scriptType=groovy
enabled=true
id=hello.world
name=Hello World!
file_0=firstApp.groovy
This application file looks for a script listed in the file_
lines. Here, it's titled firstApp.groovy
inside the same directory as the application. For this example, our script is simply:
import io.deephaven.appmode.ApplicationContext
import io.deephaven.appmode.ApplicationState
def start = { ApplicationState app ->
size = 42
app.setField("hello", emptyTable(size))
app.setField("world", timeTable("00:00:01"))
}
ApplicationContext.initialize(start)
In our hello world example, we initialize the Deephaven libraries ApplicationContext
and ApplicationState
:
ApplicationContext
is used at the initial invocation of application mode, when the Deephaven container is started.ApplicationState
will collect the state of each application.
Applications expose fields to connecting API Clients, including the web client, by interacting with the provided ApplicationState
.
Each application has its own state that it can manipulate. This enables similar applications to co-exist without stepping on one another.
In this example, we have one method (start
) that is passed to ApplicationContext
to run when the container starts. Inside this method, we set two fields:
- An empty table.
- A timetable that will update each second.
Script Applications may directly manipulate variables bound in the REPL in addition to, or instead of, using the ApplicationContext
and ApplicationState
portions of the Application Mode API.
Once you have these two files inside the app.d
directory, it is time to start the Deephaven containers.
Inside your Deephaven directory, start the containers with the normal Docker command.
docker compose --env-file default_groovy.env up
You will observe in the start up that two exports are found inside the prompt that refer to our two fields inside the firstApp.py
or firstApp.groovy
script.
Launch the Deephaven IDE in your web browser. Open the Panels menu to see the defined tables hello
and world
.
Now that you know how to configure Application Mode, you are empowered to:
- Create all data sources your application needs to function without human interaction.
- Configure and expose commonly viewed plots.
- Prepare the REPL environment with variables, functions, and classes, enabling you to get down to business more quickly.
Multiple Script Application example
In the first script we define tables. We can then access those tables in the Deephaven IDE by making them global, or we can use those tables in future scripts.
Here we add to the .app
file to run another script:
type=script
scriptType=groovy
enabled=true
id=hello.world
name=Hello World!
file_0=firstApp.groovy
file_1=secondApp.groovy
Files are run in numerical order (after removing the prefix file_
). Anything created in the file_0
can be accessed in file_1
. Here we keep file_0
the same, and add a file_1
defined as:
import io.deephaven.appmode.ApplicationContext
import io.deephaven.appmode.ApplicationState
def start = { ApplicationState app ->
my_new_table = app.getField("world").value()
my_new_table = my_new_table.update("A=i")
QueryScope.addParam("my_new_table", my_new_table)
}
ApplicationContext.initialize(start)
These scripts allow only the my_new_table
to be available to the query scope, while the other tables are only available in the Panels menu. If you want to perform queries on fields defined in application mode, they need to be explicitly assigned to the query scope inside the applications.
Other application modes
The other application modes are just as easily configured. You can write applications in other JVM-based language such as Java/Scala/Kotlin and then access them from the REPL via scripting mechanics. This can be done with either static or dynamic applications.
Static Applications
Static Applications define all the fields at the creation of the instance. These applications are useful for applications in which all fields are known and accessible at all times.
The subclass to implement is io.deephaven.appmode.StaticClassApplication
. Be sure to package this into a jar file and provide it as a third-party dependency to Deephaven’s server. See How to install Java packages for more information.
The .app
configuration file is as follows:
type=static
class=fully.qualified.class.Name
enabled=true
Dynamic Applications
Dynamic Applications allow for fields to be created and removed during the instance. These applications are useful when fields might be created or removed with time or as data changes.
The subclass to implement is io.deephaven.appmode.DynamicApplication
for making your app a dynamic application. Be sure to package this into a jar file and provide it as a third-party dependency to Deephaven’s server. See How to install Java packages for more information.
The .app
configuration file is as follows:
type=dynamic
class=fully.qualified.class.Name
enabled=true
Hands-free; production-ready