CPA 2016 Communicating Generators in JavaScript Kurt Micallef ( - - PowerPoint PPT Presentation

cpa 2016 communicating generators in javascript
SMART_READER_LITE
LIVE PREVIEW

CPA 2016 Communicating Generators in JavaScript Kurt Micallef ( - - PowerPoint PPT Presentation

CPA 2016 Communicating Generators in JavaScript Kurt Micallef ( kurtmica@live.com ) Kevin Vella ( kevin.vella@um.edu.mt ) Department of Computer Science University of Malta 1 of 21 Problems and Opportunities 1 Single-threaded, event-driven


slide-1
SLIDE 1

1 of 21

CPA 2016 Communicating Generators in JavaScript

Kurt Micallef (kurtmica@live.com) Kevin Vella (kevin.vella@um.edu.mt)

Department of Computer Science University of Malta

slide-2
SLIDE 2

2 of 21

Problems and Opportunities

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

slide-3
SLIDE 3

2 of 21

Problems and Opportunities

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

slide-4
SLIDE 4

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1Mozilla Developer Network

slide-5
SLIDE 5

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1 var

generatorFunction = function* (){

2

var ret = yield 1;

3

return ret;

4 }; 1Mozilla Developer Network

slide-6
SLIDE 6

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1 var

generatorFunction = function* (){

2

var ret = yield 1;

3

return ret;

4 }; 5 6 var

generator = generatorFunction ();

1Mozilla Developer Network

slide-7
SLIDE 7

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1 var

generatorFunction = function* (){

2

var ret = yield 1;

3

return ret;

4 }; 5 6 var

generator = generatorFunction ();

7 var x = generator.next () 1Mozilla Developer Network

slide-8
SLIDE 8

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1 var

generatorFunction = function* (){

2

var ret = yield 1;

3

return ret;

4 }; 5 6 var

generator = generatorFunction ();

7 var x = generator.next ().value; // x = 1 1Mozilla Developer Network

slide-9
SLIDE 9

3 of 21

JavaScript Generators

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.1

1 var

generatorFunction = function* (){

2

var ret = yield 1;

3

return ret;

4 }; 5 6 var

generator = generatorFunction ();

7 var x = generator.next ().value; // x = 1 8 var y = generator.next (2).value; // y = 2 1Mozilla Developer Network

slide-10
SLIDE 10

4 of 21

Generators

1 var

delegate = function* (){

2

yield 1;

3 };

slide-11
SLIDE 11

4 of 21

Generators

1 var

delegate = function* (){

2

yield 1;

3 }; 4 5 var

generator = (function* (){

6

yield* delegate ();

7 }());

slide-12
SLIDE 12

4 of 21

Generators

1 var

delegate = function* (){

2

yield 1;

3 }; 4 5 var

generator = (function* (){

6

yield* delegate ();

7 }()); 8 9 var x = generator.next ().value; // x = 1

slide-13
SLIDE 13

5 of 21

Problems and Opportunities (revisited)

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

slide-14
SLIDE 14

5 of 21

Problems and Opportunities (revisited)

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

  • However JavaScript generators enable the dynamic execution
  • f a function.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

slide-15
SLIDE 15

5 of 21

Problems and Opportunities (revisited)

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

  • However JavaScript generators enable the dynamic execution
  • f a function.
  • These can be repurposed as co-generators to provide

co-operative multitasking in a CSP demeanour.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

slide-16
SLIDE 16

6 of 21

The CSP Environment and Dispatcher

  • Generators are initialised in a CSP environment, and execute

together as co-generators.

  • These are contained within a function scope, the dispatcher.

2Except CSP environment creation and channel creation.

slide-17
SLIDE 17

6 of 21

The CSP Environment and Dispatcher

  • Generators are initialised in a CSP environment, and execute

together as co-generators.

  • These are contained within a function scope, the dispatcher.

Dispatcher g1 g0 gn

Figure: Execution flow of co-generators.

2Except CSP environment creation and channel creation.

slide-18
SLIDE 18

6 of 21

The CSP Environment and Dispatcher

  • Generators are initialised in a CSP environment, and execute

together as co-generators.

  • These are contained within a function scope, the dispatcher.

Dispatcher g1 g0 gn

Figure: Execution flow of co-generators.

  • All API functions2 must be:
  • Called within a CSP environment.
  • Prefixed with a yield.

2Except CSP environment creation and channel creation.

slide-19
SLIDE 19

6 of 21

The CSP Environment and Dispatcher

  • Generators are initialised in a CSP environment, and execute

together as co-generators.

  • These are contained within a function scope, the dispatcher.

Dispatcher g1 g0 gn

Figure: Execution flow of co-generators.

  • All API functions2 must be:
  • Called within a CSP environment.
  • Prefixed with a yield.
  • yield on its own is effectively a part of the API.

2Except CSP environment creation and channel creation.

slide-20
SLIDE 20

7 of 21

API functions: process creation

1 csp.csp( 2

function* (){ },

3

// ...

4

function* (){ }

5 );

Similar to occam’s top-level PAR.

slide-21
SLIDE 21

7 of 21

API functions: process creation

1 csp.csp( 2

function* (){ },

3

// ...

4

function* (){ }

5 );

Similar to occam’s top-level PAR.

1 csp.csp(function* (){ 2

yield csp.fork(

3

function* (){ },

4

// ...

5

function* (){ }

6

);

7 });

slide-22
SLIDE 22

7 of 21

API functions: process creation

1 csp.csp( 2

function* (){ },

3

// ...

4

function* (){ }

5 );

Similar to occam’s top-level PAR.

1 csp.csp(function* (){ 2

yield csp.fork(

3

function* (){ },

4

// ...

5

function* (){ }

6

);

7 }); 1 csp.csp(function* (){ 2

yield csp.co(

3

function* (){ },

4

// ...

5

function* (){ }

6

);

7 });

Similar to occam’s PAR.

slide-23
SLIDE 23

8 of 21

API functions: Channel communication

1 var channel = new csp.Channel (); 2 3 csp.csp(function* (){ 4

var x = yield channel.recv (); // x = 1

5 }, function* (){ 6

yield channel.send (1);

7 });

slide-24
SLIDE 24

9 of 21

API functions: Timeouts

1 csp.csp(function* (){ 2

// ...

3

yield csp.timeout(csp.clock () + 1000);

4

// continue after current time + 1 second

5 });

Similar behaviour to occam’s TIMERs.

slide-25
SLIDE 25

9 of 21

API functions: Timeouts

1 csp.csp(function* (){ 2

// ...

3

yield csp.timeout(csp.clock () + 1000);

4

// continue after current time + 1 second

5 });

Similar behaviour to occam’s TIMERs.

1 csp.csp(function* (){ 2

// ...

3

yield csp.sleep (1000);

4

// continue after current time + 1 second

5 });

Similar to popular programming languages’ Thread.sleep().

slide-26
SLIDE 26

10 of 21

API functions: Choice

1 var channel = new csp.Channel (); 2 3 csp.csp(function* (){ 4

yield csp.choice ({

5

recv: channel ,

6

action: function* (x) { /* ... */ }

7

}, {

8

timeout: 1000 ,

9

action: function* () { /* ... */ }

10

}, {

11

boolean: true ,

12

action: function* () { /* ... */ }

13

});

14 });

Similar to occam’s ALT.

slide-27
SLIDE 27

11 of 21

Problems and Opportunities (re-revisited)

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

slide-28
SLIDE 28

11 of 21

Problems and Opportunities (re-revisited)

1 Single-threaded, event-driven JavaScript limits the scope for

concurrency.

2 JavaScript is a ubiquitous computing technology, running in

browsers, server runtimes (Node.js) and worker contexts.

  • CSP environments can be distributed over several distinct

JavaScript instances to achieve parallel execution.

slide-29
SLIDE 29

12 of 21

External Channels

  • External channels extend across JavaScript instances by
  • verlying various communication mechanisms.

JavaScript JavaScript CSP environment CSP environment External Channel generator communication

  • bject

generator communication

  • bject
slide-30
SLIDE 30

12 of 21

External Channels

  • External channels extend across JavaScript instances by
  • verlying various communication mechanisms.

JavaScript JavaScript CSP environment CSP environment External Channel generator communication

  • bject

generator communication

  • bject
  • JavaScript environments investigated: browsers, Node.js, and

workers.

  • Transport mechanisms used: socket.io (over WebSockets),

Web Workers, and Cluster Workers.

slide-31
SLIDE 31

13 of 21

External Channels – DistributedChannel

External channel implementation over socket.io (WebSocket).

1 http.createServer ().listen (8000); 2 io.on("connection", function (s){ 3

var channel = new csp. DistributedChannel (s,"id");

4 5

csp.csp(function* (){

6

var x = yield channel.recv ();

7

});

8 }); 1 var s = io.connect("http :// serverhost :8000/"); 2 var channel = new csp. DistributedChannel (s,"id"); 3 4 csp.csp(function* (){ 5

yield channel.send (1);

6 });

Listing: Channel communication between distributed co-generators.

slide-32
SLIDE 32

14 of 21

External Channels – WorkerChannel

External Channel implementation over workers: Web Workers and Node.js Cluster Workers.

1 var worker = new Worker("worker.js"); 2 var channel = new csp. WorkerChannel (worker); 3 4 csp.csp(function* (){ 5

var x = yield channel.recv ();

6 }); 1 var channel = new csp. WorkerChannel (self); 2 3 csp.csp(function* (){ 4

yield channel.send (1);

5 });

Listing: Channel communication between co-generators across Web Workers.

slide-33
SLIDE 33

15 of 21

Recall Channels

Syntactic and semantic equivalence across channels over all types

  • f communication mechanisms!

1 var channel = new csp.Channel (); 2 3 csp.csp(function* (){ 4

var x = yield channel.recv (); // x = 1

5 }, function* (){ 6

yield channel.send (1);

7 });

slide-34
SLIDE 34

16 of 21

External Channels – communication protocol

  • Synchronize-then-communicate protocol used to alleviate any

race conditions.

slide-35
SLIDE 35

16 of 21

External Channels – communication protocol

  • Synchronize-then-communicate protocol used to alleviate any

race conditions.

co-generator performed local communication synchronized co-generator arrived on channel co-generator arrived on channel synchronizing synchronizing & waiting for co- generator waiting for co- generator communicating distributed communication done & no longer in sync synchronized

slide-36
SLIDE 36

16 of 21

External Channels – communication protocol

  • Synchronize-then-communicate protocol used to alleviate any

race conditions.

co-generator performed local communication synchronized co-generator arrived on channel co-generator arrived on channel synchronizing synchronizing & waiting for co- generator waiting for co- generator communicating distributed communication done & no longer in sync synchronized

  • This protocol allows further external channel implementations!
slide-37
SLIDE 37

17 of 21

Performance: Co-generator Execution

2 000 4 000 6 000 8 000 10 000 20 40 60 80 100 Number of Generators Co-generator Execution Time /µs

Node.js Chrome Firefox Figure: Scaling up co-generators in a CSP environment.

slide-38
SLIDE 38

18 of 21

Performance: Message Transmission

50 000 100 000 150 000 200 000 5 10 15 20 Message Size /bytes Message Transmission Time /ms

Node.js Chrome Firefox Figure: Scaling up message size over distributed channels.

slide-39
SLIDE 39

19 of 21

Use Cases – Synchronous JavaScript

1 var promise = new

Promise(function (resolve ,reject) {

2

setTimeout(function callback (){

3

resolve("csp");

4

}, 1000);

5 });

slide-40
SLIDE 40

19 of 21

Use Cases – Synchronous JavaScript

1 var promise = new

Promise(function (resolve ,reject) {

2

setTimeout(function callback (){

3

resolve("csp");

4

}, 1000);

5 }); 6 7 promise.then(function (x){ 8

console.log(x); // "csp"

9 });

slide-41
SLIDE 41

19 of 21

Use Cases – Synchronous JavaScript

1 var promise = new

Promise(function (resolve ,reject) {

2

setTimeout(function callback (){

3

resolve("csp");

4

}, 1000);

5 }); 6 7 promise.then(function (x){ 8

console.log(x); // "csp"

9 }); 1 var channel = csp.Channel (); 2 3 csp.csp(function* (){ 4

yield csp.sleep (1000);

5

yield channel.send("csp");

6 }

slide-42
SLIDE 42

19 of 21

Use Cases – Synchronous JavaScript

1 var promise = new

Promise(function (resolve ,reject) {

2

setTimeout(function callback (){

3

resolve("csp");

4

}, 1000);

5 }); 6 7 promise.then(function (x){ 8

console.log(x); // "csp"

9 }); 1 var channel = csp.Channel (); 2 3 csp.csp(function* (){ 4

yield csp.sleep (1000);

5

yield channel.send("csp");

6 }, function* (){ 7

var x = yield channel.recv (); // "csp"

8 });

slide-43
SLIDE 43

20 of 21

Use Cases – Parallel Computing

same code base

external channel external channel external channel external channel local channel local channel

Figure: Concurrent code is reused in different distributed configurations.

slide-44
SLIDE 44

20 of 21

Use Cases – Parallel Computing

2 4 6 8 2 4 6 8 Number of Workers Speed-up

computation only w/ data harvesting Figure: Mandelbrot set computation speed-up.

slide-45
SLIDE 45

21 of 21

Conclusions

  • A straightforward CSP library implementation in JavaScript

was achieved by following the occam language and the ‘Networks, Routers, and Transputers’ design.

slide-46
SLIDE 46

21 of 21

Conclusions

  • A straightforward CSP library implementation in JavaScript

was achieved by following the occam language and the ‘Networks, Routers, and Transputers’ design.

  • Extending the implementation with external channels is useful

because:

  • The transport mechanism is abstracted away, alleviating the

need to tailor code to its location.

  • JavaScript’s parallel computing capabilities can be harnessed

at a higher level of abstraction.

slide-47
SLIDE 47

21 of 21

Conclusions

  • A straightforward CSP library implementation in JavaScript

was achieved by following the occam language and the ‘Networks, Routers, and Transputers’ design.

  • Extending the implementation with external channels is useful

because:

  • The transport mechanism is abstracted away, alleviating the

need to tailor code to its location.

  • JavaScript’s parallel computing capabilities can be harnessed

at a higher level of abstraction.

  • By using eval(), simple run-time code mobility can be

achieved since co-generators already use transport-agnostic channels.

slide-48
SLIDE 48

21 of 21

Conclusions

  • A straightforward CSP library implementation in JavaScript

was achieved by following the occam language and the ‘Networks, Routers, and Transputers’ design.

  • Extending the implementation with external channels is useful

because:

  • The transport mechanism is abstracted away, alleviating the

need to tailor code to its location.

  • JavaScript’s parallel computing capabilities can be harnessed

at a higher level of abstraction.

  • By using eval(), simple run-time code mobility can be

achieved since co-generators already use transport-agnostic channels.

  • Distributed failures: how best to handle them in CSP-like

systems?