Big Dieselapps Overview Pub

Here's the big Dieselapps overview. Each section links to detailed topics.

Markup, Wikis and DSL

Dieselapps is based on a Markdown Wiki with DSL (Domain Specific Language). Every "page" is a wiki topic, with a category, content and tags. The category and the tags are meaningful, see stories and specs below.

Basically, the wiki pages are written in markdown and can contain specific DSL instructions, for example this one declares a message

## This is an example topic

With some floating text, and...

$msg home.guest_arrived(name:String) : (welcome)

Read more details at Markup and DSL

The rules engine

If you're wondering what the DSL is used for, among the few capabilities like domain modelling etc, the most important is defining and using rules for the embedded rules engine. See DSL Reference for details on the current DSL capabilities (it is an extensible framework).

A rule defines the behavior for a specific message or event - in this case generates another message (chimes.welcome) and derives a new value in context (welcome), which are the typical things you do:

$when home.guest_arrived(name == "Jane")
=> chimes.welcome(name="Jane")
=> (welcome = "Welcome, ${name}")

A message looks much like a function, it has a qualified name and a list of attributes or parameters as well as a resulting list of attributes - you can declare a message's signature:

$msg home.guest_arrived(name) : (welcome)

$msg elk.devices.query(name) : (deviceList, totalCount)

The attributes can be typed, have default values etc, see more in Message. The actual rules to handle these messages, those defined with the $when or $mock keywords usually add conditions on these attributes, for instance this rule only welcomes Jane:

$when home.guest_arrived(name == "Jane")
=> chimes.welcome(name="Dear Jane")

Abstract message

So what are these messages? They could be things like

  • an external event or API call
  • a call out to an executor like snakk.json (there are many built in Default executors)
  • a container for other messages
  • etc

The rules engine decomposes messages based on these rules. A flow can be started in several ways, the most common is via an API call and, for instance if you want a simple API:

$mock (path ~path "/account2/404/id") 
=> diesel.flow.return(
    payload="Nope, 404 is mine...",
    diesel.http.response.header.myHeader = "mine",

Nodes and traces

During a flow's execution, the flow will look like nodes in a tree, based on the rules that were found applicable, which decomposed into other messages and so on. The nodes are generally messages, values/variables, or just other information (logs etc).

When you see a trace, you can hover on the colored tags for additional details and info and click them, if the cursor changes to a hand, to see where that element was generated from.

You can see these traces if you select one flow in the flow viewer, or when editing a Story in either the fiddle or the main editor with the "trace" checkbox enabled.

Values and contexts

Besides messages, in a flow you can set and read values of attributes. These are stored in a "context" much like a function's variables, see above the lights value being set to "bright" or the example above, setting => (welcome=...).

These contexts are fairly intuitive, work close to what you'd expect scopes to work in regular programming languages, but there may be some gotchas as you progress to more and more complex constructs, you'll see.


The payload is a special value which is passed from message to message, you can think of it as the "current result" or the "currently returned value". Each message can set the value of payload and it is the invisible hand-off from message to message, unless the message declares a specific returned value like $msg : (myValue).

For instance in this sequence, the result of snakk.json is populated in the payload and implicitely passed on to ctx.echo:

$send snakk.json(url="...")
$send ctx.echo
Or this more explicit version:
$send ctx.echo(x=payload)


Built-in or custom Executors can handle specific messages and take action on them, these plug into the rules engine and use specific prefixes, which you should not reuse or redefine, to avoid unexpected behavior.

There are several predefined executors - these prefixes are reserved:

  • snakk - HTTP requests
  • diesel - special engine functions (like return, exceptions etc)
  • ctx - context functions (set, transform values etc)
  • wiki - interact with the wiki engine (read content, receive change events etc)

Read about these at Default executors - some of the most common are:

  • ctx.set(name=expr) to set a value
  • snakk.json(url,verb) to read a URL
  • diesel.flow.return to stop a flow and return a value
  • entry point for an API
  • ctx.echo to echo any values into the trace

The main entry-point to trigger workflows is /diesel/rest which internally raises a event, which can be handled with rules like:

$when (path ~path "/v1/ems/:env/device/:deviceType/:deviceId/config/:configRole/*configPath")
=> ems.cfg.query(env, deviceId, deviceType, configRole)

The ~path operator is special for handling URL paths and will not only match the URL but also extract the values like :configRole and *configPath which are then populated as values in the context - this notation is typical for URL router frameworks. Path elements like :env are parsed and populated as attributes in context etc - see more details in Default executors.


To reach out to other services, the snakk executor is used, the most used messages are:

  • snakk.text - read test from an URL
  • snakk.json - read json from an URL

The result is placed in payload.

Specs and stories

While all wiki topics are equal, some are special when using rules, these two categories:

  • Spec - specs can specify messages and rules
  • Story - stories can trigger messages and rules (i.e. are tests, active acceptance criteria etc)

So, the typical constructs for a spec are $mock and $when, while for stories, they would typically use $send and $expect.

Rules gotchas and features Exclusive

These two rules below would both trigger for the .../sync url, so to make only the first one trigger ang ignore the second, we'll make the first one exclusive - a rule tagged as exclusive will dominate all other applicable rules and exclude them:

$when <exclusive> (path ~path "/v1/ems/:env/device/:deviceType/:deviceId/config/sync")
=> ems.cfg.sync(env, deviceType, deviceId)

$when (path ~path "/v1/ems/:env/device/:deviceType/:deviceId/config/:configRole")
=> ems.cfg.query(env, deviceId, deviceType, configRole)

Match and decompose regex

The regex operator ~= can decompose the input based on the named matching groups, i.e. below the correlationId will be available as a value inside the rule:

$when:: timer.ticked (name ~= "check(?<correlationId>.+)")
   ctx.echo (msg=correlatio...)

The fiddle

See Diesel Fiddle Guide for details on using the fiddle.

Environments and development process

Dieselapps is ran in the cloud and a local environment. The cloud deployment cannot reach the internal network, so for development you need to use a local environment (on premises), unless all other components are avaialble from the internet.

In the cloud, there are two projects (app is your app's name):

  • devapp which is the development project, includes stories
  • app which is the production project, no test stories, just specs

Cloud development model

When developing on the cloud, you work in the devapp project and when ready, sync only the specs to the app production project. When you go to User/Diff menu from the devapp project, it will compare to the app project by default.

On premises dev model

When running local, say on mybox1, only the production project is cloned, for production.

Typical development process:

  • work local
  • when happy, sync to cloud

Was this useful?    

By: Razie | 2020-09-29 .. 2022-05-11 | Tags: academy , reference

Viewed 562 times ( | History | Print ) this page.

You need to log in to post a comment!

© Copyright DieselApps, 2012-2024, all rights reserved.