Introduction
This document describes a Calculation Engine to be used in supervisory systems for process and discrete manufacturing.This system is composed by the following components:
- Data-structures in-memory servers (mem-node)
- Computational engines (eng-node)
- Web visualization (vis-node)
- Database servers (db-node)
S4M is oriented to engineers with limited knowledge of computer science. Because of that, the selection of one simple computer language, to be used in all system’s components, was required. S4M uses Google Dart language.
The mem-nodes are responsible for fast data storage and retrieve.
Data-structures in-memory server allows the storage and retrieve, using keys, of data-structure (string, numbers, lists, sets, hashes). Data is periodic persisted.
Redis describes itself as:
Redis is
an open source, BSD licensed, advanced key-value store. It is often
referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.
You can
run atomic operations on these types, like appending to a
string; incrementing the
value in a hash; pushing to a list; computing set
intersection, union and difference; or getting the
member with highest ranking in a sorted set.
In order
to achieve its outstanding performance, Redis works with an in-memory
dataset. Depending on your use case, you can persist it either by dumping the dataset
to disk every once in a while, or by appending each
command to a log.
Redis
also supports trivial-to-setup master-slave
replication, with very fast non-blocking
first synchronization, auto-reconnection on net split and so forth.
Other
features include Transactions, Pub/Sub, Lua scripting, Keys with a
limited time-to-live, and configuration settings
to make Redis behave like a cache.
You can
use Redis from most programming
languages out there.
Redis is
written in ANSI C and works in most POSIX systems like Linux, *BSD, OS X
without external dependencies. Linux and OSX are the two operating systems
where Redis is developed and more tested, and we recommend using Linux for
deploying. Redis may work in Solaris-derived systems like SmartOS, but the
support is best effort. There
is no official support for Windows builds, but Microsoft develops and maintains
a Win32-64
experimental version of Redis.
Redis is ranked 13 in database popularity (11/16/2013) in http://db-engines.com/en/ranking.
The eng-nodes are responsible for all required computation.
S4M uses Google Dart (http://www.dartlang.com
).
Dart describes itself as:
Dart is easy to learn. A wide range of
developers can learn Dart quickly. It’s an object-oriented language with
classes, single inheritance, lexical scope, top-level functions, and a familiar
syntax. Most developers are up and running with Dart in just a few hours.
Dart compiles to JavaScript. Dart has been
designed from the start to compile to JavaScript, so that Dart apps can run
across the entire modern web. Every feature considered for the language must
somehow be translated to performant and logical JavaScript before it is added.
Dart draws a line in the sand and doesn’t support older, legacy browsers.
Dart runs in the client and on the server. The Dart virtual
machine (VM) can be integrated into a web browser, but it can also run
standalone on the command line. With built-in library support for files,
directories, sockets, and even web servers, you can use Dart for full
end-to-end apps.
Dart comes with a lightweight editor. You can use Dart
Editor to write, launch, and debug Dart apps. The editor can help you with code
completion, detecting potential bugs, debugging both command-line and web apps,
and even refactoring. Dart Editor isn’t required for writing Dart; it’s just a
tool that can help you write better code faster.
Dart supports types, without requiring them. You can omit types
when you want to move very quickly, aren’t sure what structure to take, or
simply want to express something you can’t with the type system. You can add
types as your program matures, the structure becomes more evident, and more
developers join the project. Dart’s optional types are static type annotations
that act as documentation, clearly expressing your intent. Using types means
that fewer comments are required to document the code, and tools can give
better warnings and error messages.
Dart scales from small scripts to large, complex
apps. Web development is very much an iterative process.
With the reload button acting as your compiler, building the seed of a web app
is often a fun experience of writing a few functions just to experiment. As the
idea grows, you can add more code and structure. Thanks to Dart’s support for
top-level functions, optional types, classes, and libraries, your Dart programs
can start small and grow over time. Tools such as Dart Editor help you refactor
and navigate your code as it evolves.
Dart has a wide array of built-in libraries. The core library
supports built-in types and other fundamental features such as collections,
dates, and regular expressions. Web apps can use the HTML library—think DOM
programming, but optimized for Dart. Command-line apps can use the I/O library
to work with files, directories, sockets, and servers. Other libraries include
URI, UTF, Crypto, Math, and Unit test.
Dart supports safe, simple concurrency with
isolates. Traditional
shared-memory threads are difficult to debug and can lead to deadlocks. Dart’s
isolates, inspired by Erlang, provide an easier to understand model for running
isolated, but concurrent, portions of your code. Spawning new isolates is cheap
and fast, and no state is shared. In web apps, isolates even compile to Web
workers.
Dart supports code sharing. Traditional web
programming workflows can’t integrate third-party libraries from arbitrary
sources or frameworks. With the Dart package manager (pub) and language
features such as libraries, you can easily discover, install, and integrate
code from across the web and enterprise.
Dart is open source. Dart was born for
the web, and it’s available under a BSD-style license.
Example
This example includes a task that executes a
finite-state-machine (FSM) periodically every 5 seconds. When in the “running”
state the task generates 3 random numbers.
Redis database 5 is used to store the results (random
numbers) in a hash using the hash-keys “random1”, “random2” and “random3”. The
hash key is called “task1”.
The task uses messages stored in the same key “task1” and
the hash-key “message”. The message options are: “goToPause”,”goToRun” and
“goToEnd”.
The task states are: “paused”, ”running” and “ended”.
Start the example in a server Dart VM and use the official
Redis client to send messages to the FSM.
// calceng_1.dart
// S4M - Celso Axelrud
// 12/9/2013
import "package:redis_client/redis_client.dart";
import "dart:math" as math;
import "dart:async" as async;
main() {
var connectionString = "127.0.0.1:6379";
List CalcRand(RedisClient client){
List r=[0.0,0.0,0.0];
var r1 = new math.Random();
var r2 = new math.Random();
var r3 = new math.Random();
double r1a=r1.nextDouble();
double r2a=r2.nextDouble();
double r3a=r3.nextDouble();
client.hset("task1", "random1", r1a);
client.hset("task1", "random2", r2a);
client.hset("task1", "random3", r3a);
r[0]=r1a;r[1]=r2a;r[2]=r3a;
return r;
}
//Connect to Redis
RedisClient.connect(connectionString)
.then((RedisClient client) {
//Use db5
client.select(5).then((_)=>print("selected"));
List r10;
//Task1 -----------------------
String task1State='paused';
String task1Message="";
new async.Timer.periodic(new Duration(seconds:5),
(t){
//r10=CalcRand(client);
//print('timer $t , $r10');
//get message
client.hget("task1", "message")
.then((String reply){
print("Message: $reply");
task1Message=reply;
} );
//clear message
client.hset("task1","message","")
.then((_)=>print("clear"));
switch(task1Message)
{
case 'goToRun':
task1State='running';
break;
case 'goToPause':
task1State='paused';
break;
case 'goToEnd':
task1State='ended';
t.cancel();
break;
default:
break;
}
//set state
client.hset("task1","state",task1State)
.then((_)=>print("state setted: $task1State "));
switch(task1State)
{
case 'running':
r10=CalcRand(client);
print("calc random: $r10");
break;
default:
break;
}
}
);
}
)
.catchError((e)=>print("Error 2:$e"));
}
This post is also available at https://skydrive.live.com/view.aspx?cid=BDC87EF39B001785&resid=BDC87EF39B001785%2122481&app=Word&wdo=1