In the Back of Your Mind
Upcoming SlideShare
Loading in...5
×
 

In the Back of Your Mind

on

  • 1,514 views

Some simple examples of how to pipeline data through beanstalkd or 0MQ, using Dominic memory encoding as an example.

Some simple examples of how to pipeline data through beanstalkd or 0MQ, using Dominic memory encoding as an example.

Statistics

Views

Total Views
1,514
Views on SlideShare
1,514
Embed Views
0

Actions

Likes
2
Downloads
10
Comments
5

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

15 of 5 Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • again: thank you for sharing & careing
    Are you sure you want to
    Your message goes here
    Processing…
  • I agree with pretty much everything you've said. I've recently switched to using Speaker Deck, for putting my presentations online (for these and other reasons):

    http://speakerdeck.com/u/jeg2

    You can now download a PDF from there.
    Are you sure you want to
    Your message goes here
    Processing…
  • my proposal would be to only provide pdf (easy to create from keynote).

    if you want to provide the whole presentation, you can publish a libreoffice/openoffice or microsoft office presentation. so there is no operation system barrier, but providing keynote only, you look out the other systems because opening keynote file on other systems is not as easy as the oposite way.

    or you can provide keynote or pdf here and upload the other one to a file sharing system or you can upload this presentation here twice.

    thank you for shareing your cool presentation, thank you for allowing to download the presentation, thank you for careing to answer, thank you for your work. go this one step further and be operationsystem independent.
    Are you sure you want to
    Your message goes here
    Processing…
  • Hmm, I don't see a way for me to provide both. :(
    Are you sure you want to
    Your message goes here
    Processing…
  • pdf for non-mac user would be great
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

In the Back of Your Mind In the Back of Your Mind Presentation Transcript

  • IN THE BACK OF YOUR MIND beanstalkd and 0MQ through the Dominic System
  • THE DOMINIC SYSTEM
  • LEARN HOW TO IMPROVE YOUR MINDA book I am currently reading
  • MEMORY TECHNIQUES
  • MEMORY TECHNIQUES• The book includes various techniques for improving memory
  • MEMORY TECHNIQUES• The book includes various techniques for improving memory• Ithelps to translate abstract data (the brain is weak with) into vivid images (a strength of the brain)
  • MEMORY TECHNIQUES• The book includes various techniques for improving memory• Ithelps to translate abstract data (the brain is weak with) into vivid images (a strength of the brain)• The Dominic System is used to translate numbers into characters and actions • It can help you memorize large numbers
  • SINGLE DIGITS
  • SINGLE DIGITS• Just count through the alphabet • But replace F with S • And skip to N when you hit 9
  • SINGLE DIGITS 1 A 2 B• Just count through the 3 C alphabet 4 D 5 E • But replace F with S 6 S • And skip to N when you 7 G hit 9 8 H 9 N 0 O
  • DOUBLE DIGITS
  • DOUBLE DIGITS• Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA
  • DOUBLE DIGITS• Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA• Use the letters as initials for a character • AE = Albert Einstein, BG = Bill Gates, CN = Chuck Norris
  • DOUBLE DIGITS• Convert digit pairs into letters • 15 = AE, 23 = BC, 27 = BG, 39 = CN, 80 = HO, 80 = HA• Use the letters as initials for a character • AE = Albert Einstein, BG = Bill Gates, CN = Chuck Norris• Or use letters to indicate characters in other ways • BC = Jesus Christ, HO = Santa Claus, HA = Julia Sweeney
  • IMAGERY IS KEY
  • IMAGERY IS KEY• Each digit pair should create an image in your mind
  • IMAGERY IS KEY• Each digit pair should create an image in your mind• The image need to be a character doing their signature action • Chuck Norris performing a roundhouse kick • Santa Claus delivering presents • Julia Sweeney dressing asexually
  • FOUR DIGIT NUMBERS
  • FOUR DIGIT NUMBERS• Tohandle four digit numbers, use the first two for the character and the second two as the action • 2339 = BCCN = Jesus Christ performing a roundhouse kick • 8081 = HOHA = Santa Claus dressing asexually
  • FOUR DIGIT NUMBERS• Tohandle four digit numbers, use the first two for the character and the second two as the action • 2339 = BCCN = Jesus Christ performing a roundhouse kick • 8081 = HOHA = Santa Claus dressing asexually• You’re up to a 10,000 number memory at this point!
  • LARGER NUMBERS
  • LARGER NUMBERS• “Chunk” up bigger numbers into two and four digit groups
  • LARGER NUMBERS• “Chunk” up bigger numbers into two and four digit groups• Build wacky stories using those characters and actions • 27808039 = 2780 8039 = BGHO HOCN = Bill Gates started delivering presents, but this angered Santa Claus who gave him a roundhouse kick.
  • A CAST OF CHARACTERS
  • A CAST OF CHARACTERShttp://ron.ludism.org/mnemonics_public.txt…40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba DOo!)41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch Hikers Guide to the Galaxy_)42 = DB = PERSONAL43 = DC = George Washington, chopping down cherry tree (Washington DC)44 = DD = Danny Dunn (fictional character), descending in a bathysphere45 = DE = PERSONAL46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox47 = DG = PERSONAL48 = DH = Douglas Hofstadter, recursively holding a picture of himself49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on Christmas lights…
  • A CAST OF CHARACTERShttp://ron.ludism.org/mnemonics_public.txt…40 = DO = Fred Flintstone, breaking rocks in the quarry (Yabba dabba DOo!)41 = DA = Douglas Adams, putting a Babelfish into his ear (_The Hitch Hikers Guide to the Galaxy_)42 = DB = PERSONAL43 = DC = George Washington, chopping down cherry tree (Washington DC)44 = DD = Danny Dunn (fictional character), descending in a bathysphere45 = DE = PERSONAL46 = DS = Ivan Stang (a.k.a. Doug Smith), ranting on a soapbox47 = DG = PERSONAL48 = DH = Douglas Hofstadter, recursively holding a picture of himself49 = DN = Dan (_Roseanne_ TV show), wearing sunglasses to switch on Christmas lights…
  • BEANSTALKD (VIA STALKER)
  • BEANSTALKD
  • BEANSTALKD•A simple but highly effective message queue
  • BEANSTALKD•A simple but highly effective message queue• I’ve used it many times, including to do moves in Go vs Go
  • BEANSTALKD•A simple but highly effective message queue• I’ve used it many times, including to do moves in Go vs Go• It’s definitely one of my favorite tools for background jobs
  • CHARACTER LOOKUPS
  • CHARACTER LOOKUPSrequire "open-uri"def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_tableend
  • CHARACTER LOOKUPSrequire "open-uri"def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_tableend
  • CHARACTER LOOKUPSrequire "open-uri"def lookup_table return @lookup_table if defined? @lookup_table @lookup_table = { } open("http://ron.ludism.org/mnemonics_public.txt") do |page| page.each do |line| if line =~ /A(d{2})s*=s*[A-Z]{2}s*=s*(.+)/ @lookup_table[$1] = $2 elsif line =~ /As+(.+)/ @lookup_table.values.last << " #{$1}" end end end @lookup_tableend
  • ENCODING CHUNKS
  • ENCODING CHUNKSdef encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] endend
  • ENCODING CHUNKSdef encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] endend
  • ENCODING CHUNKSdef encode(n, as = :both) if n.size == 4 and as == :both "#{encode(n[0..1], :character)} #{encode(n[2..3], :action)}." elsif as == :both "#{encode(n, :character)} #{encode(n, :action)}." elsif as == :character lookup_table[n][/As*([^,]+(?:([^)]+))?)/, 1] elsif as == :action lookup_table[n][/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] endend
  • ENCODING NUMBERS
  • ENCODING NUMBERSjob "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", ") end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings )end
  • ENCODING NUMBERSjob "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", ") end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings )end
  • ENCODING NUMBERSjob "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", ") end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings )end
  • ENCODING NUMBERSjob "number.encode" do |args| number = args["number"].to_s.delete("^0-9") number = "0#{number}" if (number.size % 2).nonzero? chunks = [4] * (number.size / 4) + [2] * (number.size % 4 / 2) encodings = [ ] chunks.permutation.to_a.uniq.each do |grouping| encodings << number.match(/A#{grouping.map { |g| "(.{#{g}})" }.join}z/) .captures .map { |n| encode(n) } .join(" ") .tr("_", ") end Stalker.enqueue( "number.display", number: args["number"], encodings: encodings )end
  • DISPLAYING ENCODINGS
  • DISPLAYING ENCODINGS job "number.display" do |args| Array(args["encodings"]).each do |encoded| puts "#{args[number]}:" puts encoded puts end end
  • QUEUING NUMBERS
  • QUEUING NUMBERSabort "USAGE: #{$PROGRAM_NAME} NUMBER" if ARGV.empty?require "stalker"Stalker.enqueue("number.encode", number: ARGV.shift)
  • RUNNING JOBS
  • RUNNING JOBS$ beanstalkd
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms
  • RUNNING JOBS$ beanstalkd$ ruby encode_number.rb 405-285-0536$ rvm 1.9.2$ RUBYLIB=. stalk jobs.rb number.encode[2010-12-08 13:07:24 -0600] Working 1 jobs: [ number.encode ][2010-12-08 13:11:18 -0600] -> number.encode (number=405-285-0536)[2010-12-08 13:11:19 -0600] -> number.encode finished in 510ms$ RUBYLIB=. stalk jobs.rb number.display…405-285-0536:Fred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).Stuart Little (tiny fictional mouse wearing street clothes) releasinghelium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping intothe Wardrobe.…
  • FOR MORE INFORMATION See Railscasts #243
  • FOR MORE INFORMATION See Railscasts #243
  • BEANSTALKD PROS
  • BEANSTALKD PROS• Extremely lightweight (especially if you drop the Rails stack)
  • BEANSTALKD PROS• Extremely lightweight (especially if you drop the Rails stack)• Ridiculously fast
  • BEANSTALKD PROS• Extremely lightweight (especially if you drop the Rails stack)• Ridiculously fast• Designed to be a queue
  • BEANSTALKD PROS• Extremely lightweight (especially if you drop the Rails stack)• Ridiculously fast• Designed to be a queue• “Tubes” make it trivial to divide work or pipeline jobs
  • BEANSTALKD PROS• Extremely lightweight (especially if you drop the Rails stack)• Ridiculously fast• Designed to be a queue• “Tubes” make it trivial to divide work or pipeline jobs• Really easy to spread across ruby versions and environments
  • BEANSTALKD CONS
  • BEANSTALKD CONS• Not ideal for durable queuing needs (though it does have a binlog)
  • BEANSTALKD CONS• Not ideal for durable queuing needs (though it does have a binlog)• Missing niceties like logging (though Stalker adds logging above beanstalkd)
  • BEANSTALKD CONS• Not ideal for durable queuing needs (though it does have a binlog)• Missing niceties like logging (though Stalker adds logging above beanstalkd)• Needs job introspection
  • 0MQ(AKA ZEROMQ OR ZMQ)
  • 0MQ
  • 0MQ•A high-level socket API over an asynchronous message queue • Request and reply, publish subscribe, and pipeline models
  • 0MQ•A high-level socket API over an asynchronous message queue • Request and reply, publish subscribe, and pipeline models• This was my first time using it (I was curious about it) •I don’t think it’s well suited to this task
  • THE END OF THE PIPELINE
  • THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • THE END OF THE PIPELINE require "zmq" zmq = ZMQ::Context.new up = zmq.socket(ZMQ::UPSTREAM) up.bind("tcp://127.0.0.1:5000") while message = up.recv puts message end
  • NUMBER LOOKUPS
  • NUMBER LOOKUPS# same lookup_table() as before…def lookup lookup_table.each do |number, character_and_action| return number if yield character_and_action end nilenddef character_number(msg) lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] }enddef action_number(msg) lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] }end
  • NUMBER LOOKUPS# same lookup_table() as before…def lookup lookup_table.each do |number, character_and_action| return number if yield character_and_action end nilenddef character_number(msg) lookup { |ca| msg.start_with? ca[/As*([^,]+(?:([^)]+))?)/, 1] }enddef action_number(msg) lookup { |ca| msg.end_with? ca[/As*[^,]+(?:([^)]+))?,s*(.+?)s*z/, 1] }end
  • A DECODER
  • A DECODERdef decode(message) message.to_s.strip.split(/.(?:s{2}|n|z)/).map { |chunk| chunk.gsub!(/s+/, " ") character = character_number(chunk) action = action_number(chunk) character == action ? character : "#{character}#{action}" }.joinend
  • THE MIDDLE PIPE
  • THE MIDDLE PIPErequire "zmq"zmq = ZMQ::Context.newup = zmq.socket(ZMQ::UPSTREAM)down = zmq.socket(ZMQ::DOWNSTREAM)up.bind("tcp://127.0.0.1:5001")down.connect("tcp://127.0.0.1:5000")while message = up.recv down.send(decode(message))end
  • THE MIDDLE PIPErequire "zmq"zmq = ZMQ::Context.newup = zmq.socket(ZMQ::UPSTREAM)down = zmq.socket(ZMQ::DOWNSTREAM)up.bind("tcp://127.0.0.1:5001")down.connect("tcp://127.0.0.1:5000")while message = up.recv down.send(decode(message))end
  • THE MIDDLE PIPErequire "zmq"zmq = ZMQ::Context.newup = zmq.socket(ZMQ::UPSTREAM)down = zmq.socket(ZMQ::DOWNSTREAM)up.bind("tcp://127.0.0.1:5001")down.connect("tcp://127.0.0.1:5000")while message = up.recv down.send(decode(message))end
  • THE MIDDLE PIPErequire "zmq"zmq = ZMQ::Context.newup = zmq.socket(ZMQ::UPSTREAM)down = zmq.socket(ZMQ::DOWNSTREAM)up.bind("tcp://127.0.0.1:5001")down.connect("tcp://127.0.0.1:5000")while message = up.recv down.send(decode(message))end
  • THE PIPELINE OPENING
  • THE PIPELINE OPENING require "zmq" zmq = ZMQ::Context.new down = zmq.socket(ZMQ::DOWNSTREAM) down.connect("tcp://127.0.0.1:5001") down.send(ARGF.read)
  • A DATA PIPELINE IN ACTION
  • A DATA PIPELINE IN ACTION$ ruby queue_message.rbFred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).Stuart Little (tiny fictional mouse wearing street clothes) releasinghelium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping intothe Wardrobe.^d
  • A DATA PIPELINE IN ACTION$ ruby queue_message.rbFred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).Stuart Little (tiny fictional mouse wearing street clothes) releasinghelium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping intothe Wardrobe.^d $ ruby decoder.rb
  • A DATA PIPELINE IN ACTION$ ruby queue_message.rbFred Flintstone breaking rocks in the quarry (Yabba dabba DOo!).Stuart Little (tiny fictional mouse wearing street clothes) releasinghelium balloons (Newtonmas, HE HE HE!). J.R.R. Tolkien stepping intothe Wardrobe.^d $ ruby decoder.rb $ ruby decoder_display.rb 4052850536
  • 0MQ PROS
  • 0MQ PROS• Asynchronous messaging primitives for constructing networks
  • 0MQ PROS• Asynchronous messaging primitives for constructing networks• Extremely versatile (can be made to fit most any model)
  • 0MQ PROS• Asynchronous messaging primitives for constructing networks• Extremely versatile (can be made to fit most any model)• Supports many to many connections
  • 0MQ PROS• Asynchronous messaging primitives for constructing networks• Extremely versatile (can be made to fit most any model)• Supports many to many connections• Automatically load balanced
  • 0MQ CONS
  • 0MQ CONS• Very low-level (really just a platform to build on) • Missing all the conveniences: logging, message formats, etc.
  • 0MQ CONS• Very low-level (really just a platform to build on) • Missing all the conveniences: logging, message formats, etc.• Best for asynchronous networks you design and build
  • THANKS!