Permalink
Browse files

Reworking the worklfows.

  • Loading branch information...
Orbifold committed Jan 26, 2019
1 parent 6a35434 commit 755d757040960adb2559bd77265129707f27abc4

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -1,6 +1,6 @@
const path = require('path'),
https = require('https'),
cors = require('cors'),

fs = require('fs-extra'),
_ = require("lodash"),
Qwiery = require("../../lib") ;
@@ -11,20 +11,21 @@ process.on('uncaughtException', function(err) {
});

const express = require('express'),
cors = require('cors'),
bodyParser = require('body-parser');


const app = express();


app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.use(cors());
let PORT;
let HOST;
//app.use(cors({"credentials": true, "origin": ['*', 'http://localhost:4787', 'http://localhost:4785', 'http://localhost:63342']}));

// app.use(cors({"credentials": true, "origin": ['http://localhost:3000', 'http://localhost:4787', 'http://localhost:4785', 'http://localhost:63342']}));
app.use(cors({credentials: true, origin: 'http://localhost:3000'}));
if(false) {
// In case you want SSL, this is the kinda code you'll need.
// See here (among other) for more info https://github.com/andrewconnell/generator-nodehttps/blob/master/docs/setup-https.md
@@ -156,4 +157,4 @@ if(process.env.Platform === "Azure") {
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
}
}
@@ -67,3 +67,4 @@ and it will create a comprehensive site of both the API and the notes.
The configuration of JSDOC sits in the `jsdoc.json` file in the root of the solution.

The template to render the site is [the clean Minami](https://github.com/nijikokun/minami) but you can find lots of alternatives. The [jsdoc documentation](http://usejsdoc.org/about-configuring-default-template.html) explains in details how to configure things.

@@ -1,11 +1,21 @@

Workflows are a powerful way to handle interactions with a particular aim. They bundle a set of input-output towards the completion of a task. For example, if a user asks for the weather forecast Qwiery needs to know the location of the user. Either this personalization has been captured before or Qwiery needs to ask it explicitly. If asked it needs to somehow remember that the given answer is linked to the initial forecasting question. After this the actual forecast can be picked up from a weather service and returned. In order to achieve this coherence a workflow has to be defined which ensures that the necessary data is loaded or asked, save the intermediate state of the discussion and many other things.
Workflows are a powerful way to handle interactions with a particular aim. They bundle a set of input-output towards the completion of a task.

<hr/>

**Example**

![Weather flow](./images/WeatherFlow.png)

If a user asks for the weather forecast Qwiery needs to know the location of the user. Either this location (a personalization feature) has been captured before or Qwiery needs to ask it explicitly. If asked it needs to somehow remember that the given answer is linked to the initial forecasting question. After this the actual forecast can be picked up from a weather service and returned. In order to achieve this coherence a workflow has to be defined which ensures that the necessary data is loaded or asked, save the intermediate state of the discussion and many other things.

<hr/>

Workflows sit in a QTL template and can be inserted as an answer. When a question hits a workflow Qwiery will instantiate things and the workflow engine will kick in.

In order to write workflows it's crucial to understand the lifecycle of a workflow and how workflow states and workflow transitions function:

- at any point in time one and only one state is active. The flow activate a state by calling its `activate` method which allows the state to initialize itself.
- at any point in time one and **only one state is active**. The flow activate a state by calling its `activate` method which allows the state to initialize itself.
- when the flow is triggered the active state will handle the input through the `execute` method. This method can decide to accept or reject to move to a next state:

- the state can decide to terminate its active state by calling the `accept` method. The parameter of this method is the value used to decide which transition occurs. As long as the state does not accept the flow remains in that state.
@@ -14,7 +24,8 @@ In order to write workflows it's crucial to understand the lifecycle of a workfl
- if the state has accepted to lose its active state the workflow will first call the `deactivate` method and then perform the transition

- when the engine enters a flow it either picks up the active state (from a previous round) or looks for the unique initial state of the flow. The uniqueness of the initial state is checked during validation. Terminal states need not be unique.
- when a state has been activated after a transition it's saved for the next exchange. This effectively represents a frozen state of a discussion. The flow is saved as an active flow meaning that it has not reached a final state and the user has to either reach the terminal state or abort the whole flow. Aborting a flow can happen at any time by means of quit-like input (quit, forget about it, never mind...).
- each of the methods of a state (activate, execute, ...) raise an event picked up by the workflow engine and the data therein is used to return an answer to the user (caller). For example, when activating the initial state this will give the actual answer of the inital input. Subsequent interactions are all handled by the flow and no other plugin will interprete the input unless the flow is terminated or quit. Qwiery ensures that if there is an active flow of a user it will automatically be placed in front of any other plugin and thus hijack the natural interpreter flow or logic.

Workflow definitions are just a bit of JSON. When a workflow is defined inside a QTL template it describes a flow. When a such a flow has been instantiated it contains data from the interactions. So, a saved (serialized) flow contains both structure, logic and data.
- when a state has been activated after a transition it's saved for the next exchange. This effectively represents **a frozen state of a discussion**. The flow is saved as an active flow meaning that it has not reached a final state and the user has to either reach the terminal state or abort the whole flow. Aborting a flow can happen at any time by means of quit-like input (quit, forget about it, never mind...).
- each of the methods of a state (activate, execute, ...) raise an event picked up by the workflow engine and the data therein is used to return an answer to the user (caller). For example, when activating the initial state this will give the actual answer of the initial input. Subsequent interactions are all handled by the flow and no other plugin will interprete the input unless the flow is terminated or quit. Qwiery ensures that if there is an active flow of a user it will automatically be placed in front of any other plugin and thus hijack the natural interpreter flow or logic.

Workflow definitions are just a bit of JSON. When a workflow is defined inside a QTL template it describes a flow. When a such a flow has been instantiated it contains data from the interactions. So, a saved (serialized) flow contains both structure, logic and data.
Binary file not shown.
Oops, something went wrong.

0 comments on commit 755d757

Please sign in to comment.