SlideShare a Scribd company logo
1 of 42
Download to read offline
Streams
FunctionalJs - London - May 2014
@darachennis
A <3able Stream
// by @TooTallNate - https://gist.github.com/TooTallNate/3947591 

// npm install lame ; npm install speaker ; node mp3player.js
var fs = require('fs');
var lame = require('lame');
var Speaker = require('speaker');
fs.createReadStream(process.argv[2])
.pipe(new lame.Decoder())
.on('format', function (format) {
this.pipe(new Speaker(format));
});
A <3able Stream
// by @TooTallNate - https://gist.github.com/TooTallNate/3947591 

// npm install lame ; npm install speaker ; node mp3player.js
var fs = require('fs');
var lame = require('lame');
var Speaker = require('speaker');
fs.createReadStream(process.argv[2])
.pipe(new lame.Decoder())
.on('format', function (format) {
this.pipe(new Speaker(format));
});
Sound Soup
var fs = require('fs');
var lame = require('lame');
var Speaker = require('speaker');
!
// Cache names of mp3's in cwd
function isMp3(e) { return e.indexOf("mp3") > 1 };
var soundz = fs.readdirSync('.').filter(isMp3);
!
// Every half second, play a random sound
setInterval(function(){
blend() },500);
function rand(min, max) {
var offset = min;
var range = (max - min) + 1;
return Math.floor( Math.random() * range) +
offset;
}
function blend() {
fs.createReadStream(soundz[rand(0,soundz.length-1)])
.pipe(new lame.Decoder())
.on('format', function (format) {
this.pipe(new Speaker(format));
});
}
A brief history in
Node.js streams
UNIXy
• UNIX $ a | b | c | d
• NODE.js> a.pipe(b).pipe(c).pipe(d)
• same as:
• a.pipe(b);

b.pipe(c);

c.pipe(d);

// but, less typing for the win o/
Streams 0
• Util.pump(Readable,Writable)
Streams 1
• EventEmitter and a pipe() function.
• pipe() is an instance of the Builder Pattern
• EventEmitter is an instance of Subject/Observer
Pattern
Streams 1: Example
var Stream = require(‘stream').Stream
var util = require('util')
function MyStream () {
Stream.call(this)
}
util.inherits(MyStream, Stream)
// stream logic and state management and back-pressure
// you’re on your own (with the rest of the pipeline)
// this was error prone and painful …
Streams 2
• EventEmitter and a pipe() function.
• Readable, Writable, Duplex, Transform,
Passthrough (and classic) ‘behaviours'
• New ‘behaviours’ encourage good ‘backpressure'
handling disciplines
Streams 2: Using Readable
// From: Stream Handbook, Readable with Push
var Readable = require('stream').Readable;
var rs = new Readable;
rs.push(‘beep ‘);
rs.push(‘boopn’);
rs.push(null);
rs.pipe(process.stdout);
Streams 2: Using Readable
// From: Stream Handbook
var Readable = require('stream').Readable;
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
if (c > 'z'.charCodeAt(0)) rs.push(null);
};
rs.pipe(process.stdout); // _read called once, prints ‘a-z'
Streams 2: Pop Quiz!!!
$ node readable-popquiz.js
abcdefghijklmnopqrstuvwxyz%
$
!
Streams 2: Pop Quiz!!!
// From: Stream Handbook (tweaked)
var Readable = require('stream').Readable;
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
if (c > 'z'.charCodeAt(0)) rs.push(null);
};
rs.pipe(process.stdout); // _read called once
rs.pipe(process.stdout); // _read called twice
rs.pipe(process.stdout); // _read called three times
rs.pipe(process.stdout); // _read called four times
Streams 2: Pop Quiz!!!
$ node readable-popquiz.js
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkl
lllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvww
wwxxxxyyyyzzzz%
$
… WAT? (Think about it)
!
Streams 2: Using Writable
// From: Stream Handbook
var fs = require('fs');
var ws = fs.createWriteStream('message.txt');
ws.write('beep ‘); // Write …
setTimeout(function () {
ws.end(‘boopn'); // We’re done writing
}, 1000);
Streams 2: Using Writable
var Writable = require('stream').Writable;
var src = process.stdin;
var dst = new Writable;
dst._write = function (chunk, enc, next) {
console.log(chunk.toString());
next();
};
src.push("hit any key!");
src.pipe(dst);
Streams 2: Transform
var Transform = stream.Transform || require('readable-stream').Transform;
function Hash(algorithm, encoding, options) {
Transform.call(this, options);
this.digester = crypto.createHash(algorithm);
this.encoding = encoding;
}
util.inherits(Hash, Transform);
Hash.prototype._transform = function (chunk, enc, cb) {
var bf = (Buffer.isBuffer(chunk)) ? chunk : new Buffer(chunk, enc);
this.digester.update(bf);
cb();
};
Hash.prototype._flush = function (cb) {
this.push(this.digester.digest(this.encoding));
cb();
};
Streams 2: Transform
var hash = require('./hash.js');
var fs = require('fs');
var rs = fs.createReadStream(‘file.js’);
var md5Hash = hash.Hash('md5', 'base64');
// var sha1Hash = hash.Hash('sha1', 'base64');
rs.pipe(md5Hash).pipe(process.stdout);
Streams 2: Duplex
* Independent Readable and Writable channels
* Implement _read and _write
* Example use



- network protocols



- serial communications with hardware



- …
Know a classic stream
// From: Stream Handbook
process.stdin.on('data', function (buf) {
console.log(buf);
});
process.stdin.on('end', function () {
console.log('__END__');
});
Streams 3
• Streams2 tweaked
• API the same as Streams2
Useful modules
• @DominicTarr’s event-stream 

https://github.com/dominictarr/event-stream
• @RVagg’s through2

https://github.com/rvagg/through2
• @Raynos’s duplexer

https://github.com/Raynos/duplexer
• https://github.com/substack/stream-handbook -
@SubStack’s Stream handbook
• http://www.nearform.com/nodecrunch/dont-use-
nodes-core-stream-module#.U4I71JRdWuk - Why
@Rvagg doesn’t use node’s core stream module (&
nor should we!)
Good to know …
Meta Programming with Streams
and Pipes
Great British Node Conference	

October 8th 2013	

London	

!
Darach Ennis
Streams 101
! Readable Streams	

! IO / throughput oriented	

! Events – data, end, error, close	

! Methods – pause, resume, end, destroy	

! Writeable Streams	

! IO / throughput oriented	

! Events - drain, pause, resume, error, close	

! Methods – write, end, destroy
Streams … 4IO
! IO Oriented	

! Finite, not infinite	

! Asynchronous	

! Lazy	

! Assumes in transit data, not in memory forms	

! Great for IO. Not efficient for compute
CSV Reader .@maxogden
Beams
Streams for Compute
Beams 101
! Sources	

! Where data pours in	

! Sinks	

! Where results pop out	

! Operators	

! Filters – Drop or pass on data based on a UDF	

! Transforms – Mutate data based on a UDF	

! Branch with Filters	

! Combine with Sinks
Beams… 4CPU
! Compute Oriented	

! Infinite, not finite	

! Synchronous	

! Eager	

! Assumes in memory form, not encoded or wire data	

! Convenient for compute. Not good for IO
Beams - Branch
Beams - Combine
Ex – Fly NodeCopter with Streams!
Extend Games to Robots!
Extend?
Meta Programming
A minor problem
! Eager: a.pipe(operation).pipe(z).pipe(a);	

! Implies:



RangeError: Maximum call stack size exceeded
Goto + Modules = Magic
Extend Beam with Modules
Questions & Thanks
! npm install beam	

! Compute oriented streams	

! Branch, Combine, Filter, Transform data	

! Extend with goto and modules.	

! npm install eep	

! Beam will be integrated into eep soon	

! Eep provides aggregate windows	

! Slide, Tumble, Monotonic, Periodic	

! Stats Library	

! Ordering now supported	

! npm install nodesapiens	

! Robosapiens V1 for node.js	

! Code on github	

! https://github.com/darach
Dojo - nodeschool.io
• Basics
• Stream Adventure
• Functional Javascript

More Related Content

What's hot

Gitosis on Mac OS X Server
Gitosis on Mac OS X ServerGitosis on Mac OS X Server
Gitosis on Mac OS X Server
Yasuhiro Asaka
 
Basic command for linux
Basic command for linuxBasic command for linux
Basic command for linux
gt0ne
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
Tony Fabeen
 

What's hot (20)

Advanced JavaScript build pipelines using Gulp.js
Advanced JavaScript build pipelines using Gulp.jsAdvanced JavaScript build pipelines using Gulp.js
Advanced JavaScript build pipelines using Gulp.js
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
 
2010 Smith Scripting101
2010 Smith Scripting1012010 Smith Scripting101
2010 Smith Scripting101
 
PaaS祭り - pagoda box
PaaS祭り - pagoda boxPaaS祭り - pagoda box
PaaS祭り - pagoda box
 
Linux-Fu for PHP Developers
Linux-Fu for PHP DevelopersLinux-Fu for PHP Developers
Linux-Fu for PHP Developers
 
Sacándole jugo a git
Sacándole jugo a gitSacándole jugo a git
Sacándole jugo a git
 
Gitosis on Mac OS X Server
Gitosis on Mac OS X ServerGitosis on Mac OS X Server
Gitosis on Mac OS X Server
 
A Percona Support Engineer Walkthrough on pt-stalk
A Percona Support Engineer Walkthrough on pt-stalkA Percona Support Engineer Walkthrough on pt-stalk
A Percona Support Engineer Walkthrough on pt-stalk
 
Git::Hooks
Git::HooksGit::Hooks
Git::Hooks
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your application
 
Basic command for linux
Basic command for linuxBasic command for linux
Basic command for linux
 
Perl dancer
Perl dancerPerl dancer
Perl dancer
 
Unix shell talk - RIT SSE
Unix shell talk - RIT SSEUnix shell talk - RIT SSE
Unix shell talk - RIT SSE
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
 
Linux Command Line
Linux Command LineLinux Command Line
Linux Command Line
 
Tools used for debugging
Tools used for debuggingTools used for debugging
Tools used for debugging
 
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club UkraineKubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
 
Blist
BlistBlist
Blist
 
AMS Node Meetup December presentation Phusion Passenger
AMS Node Meetup December presentation Phusion PassengerAMS Node Meetup December presentation Phusion Passenger
AMS Node Meetup December presentation Phusion Passenger
 
Dtalk shell
Dtalk shellDtalk shell
Dtalk shell
 

Viewers also liked (6)

Streams and Things
Streams and ThingsStreams and Things
Streams and Things
 
Deconstructing Lambda
Deconstructing LambdaDeconstructing Lambda
Deconstructing Lambda
 
Complex Er[jl]ang Processing with StreamBase
Complex Er[jl]ang Processing with StreamBaseComplex Er[jl]ang Processing with StreamBase
Complex Er[jl]ang Processing with StreamBase
 
Data distribution in the cloud with Node.js
Data distribution in the cloud with Node.jsData distribution in the cloud with Node.js
Data distribution in the cloud with Node.js
 
StreamBase - Embedded Erjang - Erlang User Group London - 20th April 2011
StreamBase - Embedded Erjang - Erlang User Group London - 20th April 2011StreamBase - Embedded Erjang - Erlang User Group London - 20th April 2011
StreamBase - Embedded Erjang - Erlang User Group London - 20th April 2011
 
Thing. An unexpected journey. Devoxx UK 2014
Thing. An unexpected journey. Devoxx UK 2014Thing. An unexpected journey. Devoxx UK 2014
Thing. An unexpected journey. Devoxx UK 2014
 

Similar to FunctionalJS - May 2014 - Streams

Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
The Next Linux Superpower: eBPF Primer
The Next Linux Superpower: eBPF PrimerThe Next Linux Superpower: eBPF Primer
The Next Linux Superpower: eBPF Primer
Sasha Goldshtein
 

Similar to FunctionalJS - May 2014 - Streams (20)

Spark streaming
Spark streamingSpark streaming
Spark streaming
 
Railsconf
RailsconfRailsconf
Railsconf
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Hadoop Streaming: Programming Hadoop without Java
Hadoop Streaming: Programming Hadoop without JavaHadoop Streaming: Programming Hadoop without Java
Hadoop Streaming: Programming Hadoop without Java
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
The Next Linux Superpower: eBPF Primer
The Next Linux Superpower: eBPF PrimerThe Next Linux Superpower: eBPF Primer
The Next Linux Superpower: eBPF Primer
 
Bioinformatica p4-io
Bioinformatica p4-ioBioinformatica p4-io
Bioinformatica p4-io
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 
Beginner's Guide to the nmap Scripting Engine - Redspin Engineer, David Shaw
Beginner's Guide to the nmap Scripting Engine - Redspin Engineer, David ShawBeginner's Guide to the nmap Scripting Engine - Redspin Engineer, David Shaw
Beginner's Guide to the nmap Scripting Engine - Redspin Engineer, David Shaw
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web site
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Hadoop MapReduce Streaming and Pipes
Hadoop MapReduce  Streaming and PipesHadoop MapReduce  Streaming and Pipes
Hadoop MapReduce Streaming and Pipes
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
Introduction to Assembly Language
Introduction to Assembly LanguageIntroduction to Assembly Language
Introduction to Assembly Language
 
Internet Technology and its Applications
Internet Technology and its ApplicationsInternet Technology and its Applications
Internet Technology and its Applications
 
Easy R
Easy REasy R
Easy R
 
myHadoop 0.30
myHadoop 0.30myHadoop 0.30
myHadoop 0.30
 

More from darach (7)

Big Data, Mob Scale.
Big Data, Mob Scale.Big Data, Mob Scale.
Big Data, Mob Scale.
 
Meta Programming with Streams and Pipes
Meta Programming with Streams and PipesMeta Programming with Streams and Pipes
Meta Programming with Streams and Pipes
 
Erlang/Sapiens
Erlang/SapiensErlang/Sapiens
Erlang/Sapiens
 
QCON London 2013
QCON London 2013QCON London 2013
QCON London 2013
 
EFL Munich - February 2013 - "Conversational Big Data with Erlang"
EFL Munich - February 2013 - "Conversational Big Data with Erlang"EFL Munich - February 2013 - "Conversational Big Data with Erlang"
EFL Munich - February 2013 - "Conversational Big Data with Erlang"
 
Streamy, Pipy, Analyticy
Streamy, Pipy, AnalyticyStreamy, Pipy, Analyticy
Streamy, Pipy, Analyticy
 
Tech mesh london 2012
Tech mesh london 2012Tech mesh london 2012
Tech mesh london 2012
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 

FunctionalJS - May 2014 - Streams

  • 1. Streams FunctionalJs - London - May 2014 @darachennis
  • 2.
  • 3. A <3able Stream // by @TooTallNate - https://gist.github.com/TooTallNate/3947591 
 // npm install lame ; npm install speaker ; node mp3player.js var fs = require('fs'); var lame = require('lame'); var Speaker = require('speaker'); fs.createReadStream(process.argv[2]) .pipe(new lame.Decoder()) .on('format', function (format) { this.pipe(new Speaker(format)); });
  • 4. A <3able Stream // by @TooTallNate - https://gist.github.com/TooTallNate/3947591 
 // npm install lame ; npm install speaker ; node mp3player.js var fs = require('fs'); var lame = require('lame'); var Speaker = require('speaker'); fs.createReadStream(process.argv[2]) .pipe(new lame.Decoder()) .on('format', function (format) { this.pipe(new Speaker(format)); });
  • 5. Sound Soup var fs = require('fs'); var lame = require('lame'); var Speaker = require('speaker'); ! // Cache names of mp3's in cwd function isMp3(e) { return e.indexOf("mp3") > 1 }; var soundz = fs.readdirSync('.').filter(isMp3); ! // Every half second, play a random sound setInterval(function(){ blend() },500); function rand(min, max) { var offset = min; var range = (max - min) + 1; return Math.floor( Math.random() * range) + offset; } function blend() { fs.createReadStream(soundz[rand(0,soundz.length-1)]) .pipe(new lame.Decoder()) .on('format', function (format) { this.pipe(new Speaker(format)); }); }
  • 6. A brief history in Node.js streams
  • 7. UNIXy • UNIX $ a | b | c | d • NODE.js> a.pipe(b).pipe(c).pipe(d) • same as: • a.pipe(b);
 b.pipe(c);
 c.pipe(d);
 // but, less typing for the win o/
  • 9. Streams 1 • EventEmitter and a pipe() function. • pipe() is an instance of the Builder Pattern • EventEmitter is an instance of Subject/Observer Pattern
  • 10. Streams 1: Example var Stream = require(‘stream').Stream var util = require('util') function MyStream () { Stream.call(this) } util.inherits(MyStream, Stream) // stream logic and state management and back-pressure // you’re on your own (with the rest of the pipeline) // this was error prone and painful …
  • 11. Streams 2 • EventEmitter and a pipe() function. • Readable, Writable, Duplex, Transform, Passthrough (and classic) ‘behaviours' • New ‘behaviours’ encourage good ‘backpressure' handling disciplines
  • 12. Streams 2: Using Readable // From: Stream Handbook, Readable with Push var Readable = require('stream').Readable; var rs = new Readable; rs.push(‘beep ‘); rs.push(‘boopn’); rs.push(null); rs.pipe(process.stdout);
  • 13. Streams 2: Using Readable // From: Stream Handbook var Readable = require('stream').Readable; var rs = Readable(); var c = 97; rs._read = function () { rs.push(String.fromCharCode(c++)); if (c > 'z'.charCodeAt(0)) rs.push(null); }; rs.pipe(process.stdout); // _read called once, prints ‘a-z'
  • 14. Streams 2: Pop Quiz!!! $ node readable-popquiz.js abcdefghijklmnopqrstuvwxyz% $ !
  • 15. Streams 2: Pop Quiz!!! // From: Stream Handbook (tweaked) var Readable = require('stream').Readable; var rs = Readable(); var c = 97; rs._read = function () { rs.push(String.fromCharCode(c++)); if (c > 'z'.charCodeAt(0)) rs.push(null); }; rs.pipe(process.stdout); // _read called once rs.pipe(process.stdout); // _read called twice rs.pipe(process.stdout); // _read called three times rs.pipe(process.stdout); // _read called four times
  • 16. Streams 2: Pop Quiz!!! $ node readable-popquiz.js aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkl lllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvww wwxxxxyyyyzzzz% $ … WAT? (Think about it) !
  • 17. Streams 2: Using Writable // From: Stream Handbook var fs = require('fs'); var ws = fs.createWriteStream('message.txt'); ws.write('beep ‘); // Write … setTimeout(function () { ws.end(‘boopn'); // We’re done writing }, 1000);
  • 18. Streams 2: Using Writable var Writable = require('stream').Writable; var src = process.stdin; var dst = new Writable; dst._write = function (chunk, enc, next) { console.log(chunk.toString()); next(); }; src.push("hit any key!"); src.pipe(dst);
  • 19. Streams 2: Transform var Transform = stream.Transform || require('readable-stream').Transform; function Hash(algorithm, encoding, options) { Transform.call(this, options); this.digester = crypto.createHash(algorithm); this.encoding = encoding; } util.inherits(Hash, Transform); Hash.prototype._transform = function (chunk, enc, cb) { var bf = (Buffer.isBuffer(chunk)) ? chunk : new Buffer(chunk, enc); this.digester.update(bf); cb(); }; Hash.prototype._flush = function (cb) { this.push(this.digester.digest(this.encoding)); cb(); };
  • 20. Streams 2: Transform var hash = require('./hash.js'); var fs = require('fs'); var rs = fs.createReadStream(‘file.js’); var md5Hash = hash.Hash('md5', 'base64'); // var sha1Hash = hash.Hash('sha1', 'base64'); rs.pipe(md5Hash).pipe(process.stdout);
  • 21. Streams 2: Duplex * Independent Readable and Writable channels * Implement _read and _write * Example use
 
 - network protocols
 
 - serial communications with hardware
 
 - …
  • 22. Know a classic stream // From: Stream Handbook process.stdin.on('data', function (buf) { console.log(buf); }); process.stdin.on('end', function () { console.log('__END__'); });
  • 23. Streams 3 • Streams2 tweaked • API the same as Streams2
  • 24. Useful modules • @DominicTarr’s event-stream 
 https://github.com/dominictarr/event-stream • @RVagg’s through2
 https://github.com/rvagg/through2 • @Raynos’s duplexer
 https://github.com/Raynos/duplexer
  • 25. • https://github.com/substack/stream-handbook - @SubStack’s Stream handbook • http://www.nearform.com/nodecrunch/dont-use- nodes-core-stream-module#.U4I71JRdWuk - Why @Rvagg doesn’t use node’s core stream module (& nor should we!) Good to know …
  • 26. Meta Programming with Streams and Pipes Great British Node Conference October 8th 2013 London ! Darach Ennis
  • 27. Streams 101 ! Readable Streams ! IO / throughput oriented ! Events – data, end, error, close ! Methods – pause, resume, end, destroy ! Writeable Streams ! IO / throughput oriented ! Events - drain, pause, resume, error, close ! Methods – write, end, destroy
  • 28. Streams … 4IO ! IO Oriented ! Finite, not infinite ! Asynchronous ! Lazy ! Assumes in transit data, not in memory forms ! Great for IO. Not efficient for compute
  • 31. Beams 101 ! Sources ! Where data pours in ! Sinks ! Where results pop out ! Operators ! Filters – Drop or pass on data based on a UDF ! Transforms – Mutate data based on a UDF ! Branch with Filters ! Combine with Sinks
  • 32. Beams… 4CPU ! Compute Oriented ! Infinite, not finite ! Synchronous ! Eager ! Assumes in memory form, not encoded or wire data ! Convenient for compute. Not good for IO
  • 35. Ex – Fly NodeCopter with Streams!
  • 36. Extend Games to Robots!
  • 38. A minor problem ! Eager: a.pipe(operation).pipe(z).pipe(a); ! Implies:
 
 RangeError: Maximum call stack size exceeded
  • 39. Goto + Modules = Magic
  • 40. Extend Beam with Modules
  • 41. Questions & Thanks ! npm install beam ! Compute oriented streams ! Branch, Combine, Filter, Transform data ! Extend with goto and modules. ! npm install eep ! Beam will be integrated into eep soon ! Eep provides aggregate windows ! Slide, Tumble, Monotonic, Periodic ! Stats Library ! Ordering now supported ! npm install nodesapiens ! Robosapiens V1 for node.js ! Code on github ! https://github.com/darach
  • 42. Dojo - nodeschool.io • Basics • Stream Adventure • Functional Javascript