es.move
A Framework for Writing Mobile Agent Applications in JavaScript
Mobile Agents
- What is mobility?
- What are mobile agents?
- Pros and Cons
- What solutions exist?
Mobility
- Code Mobility
- Sending code across a network
- e.g., Javascript, Java applets, Flash, etc.
- Mobile Agents / Computation
- Mobile code + data
- Can move autonomously
- Can continue execution
- Mobile Ambients
- Mobile computation + dynamic topologies
Mobile Agents - Pros
- Can reduce network load
- Asynchronous execution
- Can adapt and act autonomously
- Are not subject to legacy protocols in a large codebase
Mobile Agents - Cons
- Security - sending code over a network is dangerous!!
- A common execution environment is needed
- Difficult to design and write
- Not many solutions exist
https://cs.ucsb.edu/~vigna/publications/2004_vigna_MDM04.pdf
Existing Solutions
- JADE
- Java
- Requires complex administration
- Aglets
- Java
- Unmaintained
- Mobile-C
- C/C++
- For embedded devices
Our Solution - es.move
- Attempt to implement mobile agents in Javascript
- Goals:
- Easy to program
- Low administration overhead
- Target a wide audience
ECMAScript / Javascript
- Asynchronous
- Very commonly used
- Object oriented with functional elements
- Easy code mobility
- Easy serialization
- Runs in your browser!
Architecture
- Agents
- Environments
- Services
- Middleware
Agents
- Stateless
- Composition of functions
- Can move autonomously
- 'go here, do this, go there, do that'
Environments
- Context for agents to execute in
- Provide isolation
- Expose services to agents
- Can have many instances
- Addressable by:
- type name
- unique id
Services
- Interface to some resource
- Exposed to all agents
- Examples: Database, key-value store, state machine, filesystem, DOM
Middleware
- Currently, all agents are sent to a broker upon moving
- Broker forwards agent to the correct environment
- This is not a good model
- If the broker goes down, nothing can happen
- Agents are buffered at origin and broker
- TODO: Replace broker with nameserver, have environments communicate directly
Mobility
- Mobility primitives
- move - move to an environment and continue as function
- away - move to an environment, continue as function, return to origin
- join - join continuation for two or more aways
Mobility
- Mobility primitives
- move - move to an environment and continue as function
- away - move to an environment, continue as function, return to origin
- join - join continuation for two or more aways
-
move, away take three arguments:
- locator, behavior, params
Mobility
- locator: one of three forms for three types of movements
- <name>:any - move to any available instance of an environment
- <name>:<id> - move to a specific instance of an environment
- <name>:all - move to all instances of an environment
Mobility
- behavior: a function that will be the new behavior in the new environment
- This is the code that will be serialized and moved
- Variables above the scope of this function will not be bound in the destination environment
- params: any data that should be sent along with the behavior to its new environment
Mobility - Implementation
- Scope
- The environment binds the scope of an agent to a collection of objects
- Mobility primitive functions
- parameters
- Services
- The environment binds the scope of an agent to a collection of objects
Mobility - Implementation
-
away, join
-
Implemented using Promises
- Native feature of ES6
- Asynchronous waiting
-
Implemented using Promises
import { Broker, Environment } from 'es.move';
const environment = new Environment('stage',
new Broker('http://localhost:4815'));
environment.connect(function () {
/* I do nothing! :) */
});Example - Environment
import { Broker, Environment } from 'es.move';
const environment = new Environment('stage',
new Broker('http://localhost:4815'));
environment.connect(function () {
environment.run(function () {
let onePlusOne = 1 + 1;
console.log(`One plus one equals ${onePlusOne}`);
});
});Example - Agent
import { Broker, Environment } from 'es.move';
const environment = new Environment('stage',
new Broker('http://localhost:4815'));
environment.connect(function () {
environment.run(function () {
console.log('Ready for agents!');
});
});Example - Mobile Agent
import { Broker, Environment } from 'es.move';
const environment = new Environment('i_have_agents',
new Broker('http://localhost:4815'));
environment.connect(function () {
environment.run(function () {
console.log("This will print where I start...");
this.move('stage', function () {
console.log("And this will print where I move to!");
});
});
});import { Broker, Environment } from 'es.move';
const environment = new Environment('stage',
new Broker('http://localhost:4815'));
environment.connect(function () {
environment.run(function () {
console.log('Ready for agents!');
});
});Example - Agent with Data
import { Broker, Environment } from 'es.move';
const environment = new Environment('i_have_agents',
new Broker('http://localhost:4815'));
environment.connect(function () {
environment.run(function () {
let message = 'Hello from i_have_agents!';
this.move('stage', function () {
console.log(this.params.message);
}, { message });
});
});Example - Distributed Agent
import { Broker, Environment } from 'es.move';
const environment = new Environment('i_have_agents',
new Broker('http://localhost:4815'));
let randomArray = (length, max) => [...new Array(length)]
.map(() => Math.round(Math.random() * max));
let getAverage = function (list) {
return this.away('stage', function () {
let sum = this.params.list.reduce((b, a) => a += b );
return sum / this.params.list.length
}, { list });
};
environment.connect(function () {
environment.run(function () {
let inputData = [100, 200, 50, 20].map((x) => randomArray(1000, x));
let agents = inputData.map(getAverage.bind(this));
this.join(agents).then((results) => {
console.log(results);
});
});
});Example - Services
const environment = new Environment('my_data',
new Broker('http://localhost:4815'));
environment.registerService('myDataService', {
getMyData: () => {
return 'Some Data';
}
});
environment.connect();const environment = new Environment('i_store_data',
new Broker('http://localhost:4815'));
let dummyDataStore = new Map();
environment.registerService('dataStore', dummyDataStore);
environment.connect(function () {
environment.run(function () {
this.away('my_data', function () {
let someData = this.$.myDataService.getMyData();
}).then((data) => {
this.$.dataStore.set('myData', data);
});
});
});Example - Web Chat Room
const environment = new Environment('web_browser',
new Broker('http://chatroom.com'));
let submit = document.querySelector('#submit');
let input = document.querySelector('#input');
let messageLog = document.querySelector('#messageLog');
environment.registerService('messageLog', messageLog);
environment.connect(function () {
submit.onclick = function () {
environment.run(function () {
let message = input.text();
this.move('web_browser:all', function () {
this.$.messageLog.innerHTML += `<br>${message}`;
}, { message });
});
};
});
<html>
<head>
<script src='/es.move.js'/>
</head>
<body>
<div id='messageLog'/>
<input id='input' type='text'>
<input id='submit' type='submit'>
</body>
</html>Example - Uh Oh
const environment = new Environment('malicious',
new Broker('http://localhost:4815'));
// Kill All Stages
environment.connect(function () {
environment.run(function () {
this.move('stage:all', function () {
process.exit();
})
});
});
Example - Uh Oh
const environment = new Environment('malicious',
new Broker('http://localhost:4815'));
// Fork Bomb!
let forkBomb = function () {
this.move('stage', function () {
new Array(100000);
this.params.forkBomb();
}, { forkBomb: this.params.forkBomb });
this.move('stage', function () {
new Array(100000);
this.params.forkBomb();
}, { forkBomb: this.params.forkBomb });
}
environment.connect(function () {
environment.run(function () {
this.move('stage', forkBomb.bind(this), { forkBomb });
});
});
Future Work
- Security!
- Blacklist globals?
- Run in greater isolation?
- Restrict environments from adding agents to the system?
- Only accept agents from trusted sources?
- Sign agent code?
- Mobile ambients?
Future Work
- Decentralization
- Do we need a broker?
- Can environments talk to each other directly?
- Can security be achieved without a broker?
es.move
By Ada Young
es.move
- 313