Managing your KRL code for rulesets

When using PicoStack, code and data are combined within a pico. Together they represent some entity, which is responsive and reactive.

The code is written in KRL, the language you will need to learn (after having learned enough HTML, CSS, and JavaScript to get started). Since KRL itself consists of ASCII text (except in character strings and comments (where you can insert other UNICODE characters)), you can use your favorite text editor or  integrated development environment (IDE) to write your code.

Besides maintaining this code on your own machine, you will probably want to use a code repository in the cloud. This post explores possibilities.

Rulesets

The ruleset is the unit of compilation for KRL. The pico engine compiles (more accurately transpiles) the KRL code of the ruleset into a JavaScript module. When the pico engine receives a message for a pico, it will require that module and cause the appropriate evaluation of code in the rulesets installed in the pico.

Ruleset identifier

By convention, rulesets are named by a dot-separated name that is the reverse of a domain name that you own or control. This is very similar to the convention used in the Java programming language for class names. This is intended to avoid naming clashes as rulesets are installed in a pico.

Unlike Java, however, the compiler doesn't check that the name of the file containing a ruleset matches its Ruleset identifier (RID). Also unlike Java, there is no support or expectation that there will be a folder hierarchy for each dot-separated portion of the RID. You may arrange your KRL files in that way if you wish, or you may use some other arrangement.

Installing a ruleset into a pico

In order to run and/or test your KRL code, you will need to install it in a pico. This can be done using the Rulesets tab of the developer UI, or programmatically by sending the pico the URL of your KRL file as an attribute of a wrangler:install_ruleset_request event.

Notice that there is no way to directly install the KRL code of a ruleset into a pico. That code must be stored/hosted somewhere on the Internet, and then you make that location known to the pico.

File system

For simple applications, you can use a file: URL, such as:

file:///path/to/your/RID.krl

where you give the full path and filename of the file containing the KRL code you wish to install in a pico.

However, for serious development, you will want your code to be kept in a repository in the cloud, as well as on your local machine.

An observant reader will notice that the three rulesets built-in to the pico engine are referenced using file: URLs.

GitHub

The most common way used by KRL programmers in the author's acquaintance is to use a git repository while developing code, pushing that into a repository maintained in GitHub.

Once a KRL file is in the cloud, in a GitHub repository, there is a button labelled "Raw" that can be pushed to open a new tab containing the code. That new tab's location can then be copied and pasted into the developer UI for installation in a pico. 

The location of the KRL file could also be pasted into an event to be messaged to the pico:

http://DOMAIN:PORT/c/ECI/event/wrangler/install_ruleset_request?url=URL

In the sample above, DOMAIN, PORT, ECI, and URL must be replaced by values appropriate to your pico engine, the pico, and the location of the KRL file on the Internet. The URL may or may not be encoded as a URI component.

Drawbacks of using GitHub

While GitHub is free of cost, there are a couple of downsides to using it to hold the official copy of your ruleset source code.

  1. After you commit a code change in GitHub, some amount of time passes before the raw version of your file is available.
  2. If your GitHub repository is protected or private, the raw URL will include a token which is only valid for a short period of time. 

Both of these drawbacks make it painful to flush the ruleset, and so you will likely end up installing it each time you change your code. This is fine, but has to be done carefully to avoid losing the values in your ruleset entity variables.

Using a pico

Once you have a pico engine running in the cloud, either in an EC2 instance or on some other virtual machine that you control on the Internet, you can designate one of your picos to hold a copy of your ruleset source code.

A simple ruleset, code-repo, can provides this solution. You could build on this simplicity to do as much or as little as you want for a code repository.

The one proviso is that you need to select a pico to use this ruleset and you cannot use it to install any ruleset into that same pico.

URL for a ruleset held in the pico

At a minimum, a code repository ruleset must share a function to provide the raw code, such as:

ruleset code-repo {
  meta {
    shares code, repo
  }
  global {
    code = function(rid){
      ent:code >< rid      => ent:code.get(rid) |
      rid.match(valid_rid) => "ruleset "+rid+" {}" |
                              ""
    }
    valid_rid = re#(^\w[\w\d.-]+)$#
  }
}

Saving ruleset code by RID in the pico

It will also need a rule to allow for saving the code, which we index by RID:

  rule stashCode {
    select when code_repo new_ruleset
      rid re#(^\w[\w\d.-]+)$# setting(rid)
    fired {
      ent:code{rid} := event:attrs{"krl"}
      raise code_repo event "code_stashed" attributes event:attrs
    }
  }

A UI for the code repository pico

Finally, a simple web page to provide a minimal UI:

    repo = function(){
      form_url = <<#{meta:host}/sky/event/#{meta:eci}/none/code_repo/new_ruleset>>
      base_url = <<#{meta:host}/c/#{meta:eci}/query/#{meta:rid}/code.txt?rid=>>
      html:header("Repo")
      + <<<h1>Repo</h1>
<h2>RIDs</h2>
<ul>
#{ent:code.map(function(v,k){
  <<<li>#{k} <a href="#{base_url+k}" target="_blank">raw</a></li>
>>
}).values().join("")}</ul>
<h2>Update and edit</h2>
<form action="#{form_url}" method="POST">
<input name="rid" placeholder="rid"><br>
<textarea name="krl" placeholder="krl"></textarea><br>
<button type="submit">Submit</button>
</form>
>>
      + html:footer()
    }
  }

The page described above will look something like this:

simple web page

Showing that the ent:code entity variable contains source code for two RIDs, and the page presents the raw link for each of these, along with the form to allow for adding code for another ruleset or to edit the code of a ruleset already held by the pico.

Restoring the UI page after a code update

Finally, this rule will cause the UI page to reappear after the Submit button has done its work:

  rule redirectBack {
    select when code_repo code_stashed
    pre {
      referrer = event:attrs{"_headers"}.get("referer") // sic
    }
    if referrer then send_directive("_redirect",{"url":referrer})
  }

No comments:

Post a Comment