Lolo Company

The Lolo Company Doco

Welcome to the Lolo Company doco to help you start working with Lolo!

Guides    

Applications and Functions

Lolo Applications and Functions

Overview

This page describes many of the general concepts as well as details that are used through the process of creating an Application, writing Functions, exporting Functions and deploying an Application. The subsequent pages describe how to build and deploy an Application using much of the information contained in this page so it is useful reading before digging straight in.

Applications

The top level menu contains the "Apps" option which is the default upon login.

Applications are created (or edited) through the Apps section of the IDE. Applications consist of Functions which are conceptually nodes in a directed graph connected by routes. An Application is triggered by an event - for example, a HTTP trigger or a scheduler / timer and the data flows through the directed graph as JSON.

An Application has 4 tabs in the IDE:

  • Build
  • Settings
  • Logs
  • Docs

In the upper right the Runtime dropdown is used to specify the cloud/Kubernetes where Applications will be deployed to and the option to manage Runtimes.

Build

The Build canvas contains two sets of controls: Function Palette (on the left) and Function Controls (in the bottom right). The Function Palette contains all of the Functions in your Function Library (top level menu item - "Functions"). The Function Controls in the bottom right are used to:

  • Create a new inline JavaScript Function
  • Create new Composite Functions from two of more Functions
  • Export Functions to the Function Library
  • Copy / Paste Functions

Settings

The Settings tab contains App configuration with the following sub-tabs.

Options

Actions

There is where you delete the App.

Modules

Within a Function a package may be used as exemplified below:

const Twit = require('twit');

From within an Application, Node Package Manager packages may be imported as exemplified below:

Docs

Lolo aims to be a self documenting as possible, as such you may generate Swagger from your HTTP APIs exposed via the HTTP Trigger Library Function as well as looking for TCP / UDP ports exposed in your App. In addition to auto-documenting, there is a WYSIWYG editor to write documentation, add images and so forth.

Other relevant information such as Terms of Service, Contact Details and License can be included.

There are cases where you may want to expose documentation publicly and this is managed using the Read Permissions.

Logs

In your App, you will most likely need to log events for monitoring and debugging purposes. This can be achieved the Log Library Function or logging from within your inline JavaScript function as shown below.

exports.handler = async (ev, ctx) => {
  const { params, route, state, emit, log } = ctx;

  // logging level examples
  log.debug('debug message');
  log.trace('trace message');
  log.info('info message');
  log.warn('warning message');
  log.error('error message');
  
  route(ev);
}

Logged events are shown in the Logs tab.

Function

A new Function is created in an Application the IDE by clicking "New Function". The Function has two tabs in the IDE:

  • Handler
  • Settings

The Handler is where the inline JavaScript is written is described in the Function Lifecycle Methods section.

The Settings allows the user to do the following:

  • Set the name and description of the Function
  • Delete the Function
  • Set number of and name of input and output ports

Function Lifecycle Methods

The lifecycle methods within an inline Function are as follows:

exports.handler

The handler is invoked for each event received by the Function.

exports.handler = async(ev, ctx) => {
};

export.setup

The setup is invoked when the Application is started.

exports.setup = async ctx => {
}

Context (ctx)

The content contains the following attributes which may be used in developing Functions:

Key

Context

Description

functionId

setup / handler

Function ID

functionName

setup / handler

Function Name

appId

setup / handler

Application ID

appName

setup / handler

Application Name

inputs

setup / handler

Function Inputs

outputs

setup / handler

Function Outputs

params

setup / handler

Function parameters with all or some variables expressions resolved to actual values.

Note that variable expressions referencing event attributes will not be resolved in setup context and will still contain the template expression, such as {event.foo}

log

setup / handler

Logger object

state

handler

Shared key / value state across the Lolo Application

route(ev, output)

handler

  • Emit an event on the specified output.
  • The output argument is optional if the function has a single output.
  • Calling route in a function without outputs is a noop.

once(signal, callback, timeoutMs = 30 * 1000)

handler

  • Once and emit is an event-local pub / sub mechanism that allows communication between functions on the same event-path using signals.
  • Once is used defer the execution of a piece of code until a specific signal is observed.
  • By default, a subscriptions are automatically cancelled after 30 seconds.

emit(signal, ...args)

handler

Emit signal with optional data arguments

addHelper(name, callback)

setup

Extend the handler context by registering a helper function that will be available to all functions in the current application.

Example Function utilizing the Context

The following Function has two inputs and outputs and usage of the Context attributes is demonstrated and explained in comments.

exports.setup = async ctx => {
  const { params, route, state, log } = ctx;

}

exports.handler = async (ev, ctx) => {
  const { params, route, state, emit, log } = ctx;

  route(ev);
}

State Key / Value Store

Lolo's philosophy is aligned with the FaaS concept that functions should be small and do one thing. Most FaaS architectures are stateless, which means that the state must be stored externally and our experience is that this turns most FaaS development into an incomprehensible spaghetti of code, data storage, YAML configuration and performance challenges.

Lolo has a baked in key / value store in the Context called 'state' with a get() and set() methods which are accessible across the entire Application for better application performance, ease of understanding and making maintenance and evolution faster.

Use of state must be kept in mind in development and the following factors considered:
@Anders

Composite Functions

Composite Function are a collection of Functions which are grouped together into a sub-graph. The image below shows a shift click on nodes and the "Create Composite" button to create a Composite Function.

Once the Composite Function is create, you can double click to examine the sub-graph.

The Composite Function can then be exported to be a Library Function. To ensure a Library Function can be reused in the IDE or exposed to other frontends, a Function Schema should be added.

Function Schemas

A Function Schema is a JSON schema that provides a method for structuring and validating input into a Library Function as well as User Interface helpers that allow for applying automatic rendering.

As an example, consider the following Function which counts events with a defined value:

const { get } = require('lodash');
let counter = 0;

exports.handler = async(ev, ctx) => {
  const { route, params, log } = ctx;

  let value = get(ev,params.fieldName);
  if(value == params.fieldValue){
    counter++;
  }

  if(!ev.eof){
    return;
  }  
  let result = {
    columnName: params.fieldName,
    count : counter,
  };
  route(result);
  counter = 0;
};

A Function Schema is applied using JSON that allows the Library Function to be easily reused.

{
  "uiSchema": {
    "params": {
      "ui:options": {
        "orderable": false
      }
    },
    "fieldName": {
      "ui:help": "The field where the value will be searched",
      "ui:placeholder": "row.name"
    },
    "fieldValue": {
      "ui:help": "The value to search for",
      "ui:placeholder": "lolo"
    }
  },
  "type": "object",
  "properties": {
    "fieldName": {
      "type": "string",
      "title": "Field Name"
    },
    "fieldValue": {
      "type": "string",
      "title": "Field Value"
    }
  }
}

Using the IDE, the Function Schema can be previewed for you to build and validate the schema.

Library Functions

Library Functions are available in the IDE under Functions menu. Each Function when brought onto the Application canvas contains a "Provider" attribute that is derived from the account that the Function was published in. Control of Functions available to an Account is managed via Function Sets.

Lolo provides a base set of Library Functions to every Account.

Function Sets

Function sets are used for creating logical groups of functions that can be shared with child accounts.

Functions are automatically visible to all users in the same account, but not to users in child accounts. To share a function with a child account, you must first add it to a function set. Then, add the function set to the list of accessible functions sets for the child account. A function can be added to multiple function sets.

A function shared from a parent account will be visible in the function palette, prefixed by the provider account name. Users will be able use the function in their own apps and composite functions, but will not be able to edit or even inspect its implementation. Shared functions are not included in the function list (the "Functions" top menu item)

Functions can be shared across multiple account levels, meaning that functions sets can include both functions created in the current account, but also functions shared by a parent account.

Updated 3 months ago


Applications and Functions


Lolo Applications and Functions

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.