Fogcity Ruby meetup

Carbon Five 585 Howard St, 2nd Floor, San Francisco, CA

7:15pm - Containerized Ruby, Julian Fahrer
7:45pm — Concurrent Ruby Patterns, Gonzalo Maldonado

Containerized Ruby

  • Julian Fahrer @jufahr [email protected]
  • talk slide
  • You have most likely heard about Docker: a piece of technology that can help you with developing, shipping and running your applications. Ruby and Docker make a great team, but getting to a point where you utilize Docker in every stage in your application’s lifecycle can be tricky. We are going to address many of the common obstacles and how to overcome them. You will learn useful tips and tricks that you can apply to containerize your applications. This talk is for everybody who is interested in utilizing Docker and containers to optimize their development workflow and deployments.
  • container == processers
  • example
    vim ./Dockerfile
    
    FROM ruby:2.5.1
    COPY . /usr/src/app
    RUN bundle install
    CMD /usr/src/app/bin/start
    
    docker image build -t 
    docker container run ja
    docker image push jfaher/myimage:v1
    
  • uniform way for packaging, distributing and running
    docker contaiiner run foo/myimage:v1 rake db:migrate
    
    FROM ubuntu:18.04
    RUN apt-get update
    RUN apt-get install -y nginx
    

Patching the ContainerOS?

  • fix the security issues
  • releasing a new version of your application

  • containers should be stateless
  • container should only have one concern => no database
  • sooooo many containers => (workers and background processors, web frontend)
    • different commands, same code base
    • how to manage? => docker compose
  • but debugging?
    • easier

Concurrent Ruby Patterns. How to Speed Up Your Code Using Async Methods, Futures, and Promises

  • Gonzalo Maldonado, staff eng @lumosity
  • talk slide

  • You don’t need to switch to Go to use Channels, or to JavaScript to use Promises. Concurrent Ruby is a library that brings these features to Ruby. This talk will go over a couple practical examples of things you can do with this library.
  • Actor Model used in Celluloid
  • working with ruby threads by essee storimer

  • concurrency

exmaple with threads

threads = (1..3)map do |i|
  Thread.new(i) do |i|
    arr = instance_variable_get("@arr#{i}")
    puts "arr#{i} = #{ add(arr) }"
  end
end

threads.each {|t| t.join}

thread safety

@n = 0
3.times do 
  Thread.start { 100.times {@n += 1}}
end
# it will break
  • concurrency in other languages
    • promises in es6 js
    • async in es6
    • channel in golang
  • ruby: concurrent ruby
gem install concurrent-ruby

Async

class Echo
  include Concurrent::Async

  def echo(msg)
    print "#{msg}\n"
  end
end

horn = Echo.new
horn.echo('zero') # sync, not thread-safe
horn.async.echo('one') # async, non-blocking, thread-safe, return IVar in the :pending state
horn.await.echo('two') # sync, blocking, thread-safe, return IVar in the :complete state

Promises

  • chain concurrent operations
p = Concurrent::Promise
      .fulfill(20)
      .then { |result| result - 10 }
      .then { |result} result * 3 }
      .then(eecutor: different_executor) { |result result % 5}.execute

How:

p = Concurrent::Promise.execute{ "hello, world! "}
sleep(0.1)

p.state # :fulfilled
p.fulfilled? # true
p.value 

p = Concurrent::Promise.execute { raise StandardError.new("Here comes the Boom!")}
sleep(0.1)

p.state # :rejected
p.rejected? # true
p.reason # <StandardError>

...

Channel

  • queue operations
puts "Main thread: #{Thread.current"}"

Concurrent::Channel.go do
  puts 'Goroutin thread: #{Thread.current}'
end
c1 = Concurrent::Channel.new
c2 = Concurrent::Channel.new

Concurent::Channel.go do
  sleep(2)
  c2 << 'two'
end

Concurrent::Channel.go do
  sleep(1)
  c1 << 'one'
end

2.times do
  Concurrent::Channel.select do |s|
    s.take(c1) {|msg| print "received #{msg}\n"}
    s.take(c2) {|msg| print "received #{msg}\n"}
  end
end
  • think of channels as lightweight version of redis/resque
  • concurrency is not parallelism

Warnings

  • choose right tool for the job
    • use C or Rust from ruby using FFI
COMMENTS
Related Post