SlideShare a Scribd company logo
Debugging Ruby
 with MongoDB
    Aman Gupta
     @tmm1
debugging ruby?

• i use ruby
debugging ruby?

• i use ruby
• my ruby processes
  use a lot of ram
debugging ruby?

• i use ruby
• my ruby processes
  use a lot of ram
• i want to fix this
let’s build a debugger
• step 1: collect data
 • list of all ruby
    objects in memory
let’s build a debugger
• step 1: collect data
 • list of all ruby
    objects in memory


• step 2: analyze data
 • group by type
 • group by file/line
version 1: collect data
 • simple patch to ruby VM (300 lines of C)
  • http://gist.github.com/73674
 • simple text based output format
0x154750   @   -e:1   is   OBJECT of type: T
0x15476c   @   -e:1   is   HASH which has data
0x154788   @   -e:1   is   ARRAY of len: 0
0x1547c0   @   -e:1   is   STRING (SHARED) len: 2 and val: hi
0x1547dc   @   -e:1   is   STRING len: 1 and val: T
0x154814   @   -e:1   is   CLASS named: T inherits from Object
0x154a98   @   -e:1   is   STRING len: 2 and val: hi
0x154b40   @   -e:1   is   OBJECT of type: Range
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap

$ cat /tmp/ruby.heap | awk '{ print $3 }' | sort |
uniq -c | sort -g | tail -1

 236840 memcached/memcached.rb:316
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap

$ cat /tmp/ruby.heap | awk '{ print $3 }' | sort |
uniq -c | sort -g | tail -1

 236840 memcached/memcached.rb:316

$ grep "memcached.rb:316" /tmp/ruby.heap | awk
'{ print $5 }' | sort | uniq -c | sort -g | tail -5

     10948   ARRAY
     20355   OBJECT
     30744   DATA
     64952   HASH
    123290   STRING
version 1
version 1
• it works!
version 1
• it works!
• but...
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
 • no information about references between
    objects
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
 • no information about references between
    objects
 • limited analysis via shell scripting
version 2 goals
version 2 goals
• better data format
version 2 goals
• better data format
 • simple: one line of text per object
version 2 goals
• better data format
 • simple: one line of text per object
 • expressive: include all details about
    object contents and references
version 2 goals
• better data format
 • simple: one line of text per object
 • expressive: include all details about
    object contents and references
 • easy to use: easy to generate from C
    code & easy to consume from various
    scripting languages
JSON!
version 2 is memprof
version 2 is memprof
• no patches to ruby necessary
 • gem install memprof
 • require ‘memprof’
 • Memprof.dump_all(“/tmp/app.json”)
version 2 is memprof
• no patches to ruby necessary
 • gem install memprof
 • require ‘memprof’
 • Memprof.dump_all(“/tmp/app.json”)
• C extension for MRI ruby VM
  http://github.com/ice799/memprof
 • uses libyajl to dump out all ruby objects
    as json
Memprof.dump{
strings   }
            “hello” + “world”
Memprof.dump{
        strings                 }
                                  “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",
    "line": 1,

    "type": "string",
    "class": "0x1ba7f0",
    "class_name": "String",

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",
    "class_name": "String",

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",      address of the class object
    "class_name": "String",   “String”

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",      address of the class object
    "class_name": "String",   “String”

    "length": 10,             length and contents
    "data": "helloworld"      of this string instance
}
arrays
         Memprof.dump{
           [
             1,
             :b,
             2.2,
             “d”
           ]
         }
arrays
                             Memprof.dump{
                               [
                                 1,
                                 :b,
{
    "_id": "0x19c5c0",
                                 2.2,
                                 “d”
    "class": "0x1b0d18",       ]
    "class_name": "Array",   }

    "length": 4,
    "data": [
      1,
      ":b",

        "0x19c750",
        "0x19c598"
    ]
}
arrays
                                        Memprof.dump{
                                          [
                                            1,
                                            :b,
{
    "_id": "0x19c5c0",
                                            2.2,
                                            “d”
    "class": "0x1b0d18",                  ]
    "class_name": "Array",              }

    "length": 4,
    "data": [
      1,                     integers and symbols are
      ":b",                  stored in the array itself
        "0x19c750",
        "0x19c598"
    ]
}
arrays
                                        Memprof.dump{
                                          [
                                            1,
                                            :b,
{
    "_id": "0x19c5c0",
                                            2.2,
                                            “d”
    "class": "0x1b0d18",                  ]
    "class_name": "Array",              }

    "length": 4,
    "data": [
      1,                     integers and symbols are
      ":b",                  stored in the array itself
        "0x19c750",          floats and strings are
        "0x19c598"           separate ruby objects
    ]
}
hashes
         Memprof.dump{
           {
             :a => 1,
             “b” => 2.2
           }
         }
hashes
                               Memprof.dump{
                                 {
                                   :a => 1,
                                   “b” => 2.2
{                                }
    "_id": "0x19c598",         }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,

    "length": 2,
    "data": [
      [ ":a", 1 ],
      [ "0xc728", "0xc750" ]
    ]
}
hashes
                                        Memprof.dump{
                                          {
                                            :a => 1,
                                            “b” => 2.2
{                                         }
    "_id": "0x19c598",                  }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,

    "length": 2,
    "data": [
      [ ":a", 1 ],
                               hash entries as key/value
      [ "0xc728", "0xc750" ]   pairs
    ]
}
hashes
                                        Memprof.dump{
                                          {
                                            :a => 1,
                                            “b” => 2.2
{                                         }
    "_id": "0x19c598",                  }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,           no default proc
    "length": 2,
    "data": [
      [ ":a", 1 ],
                               hash entries as key/value
      [ "0xc728", "0xc750" ]   pairs
    ]
}
classes
          Memprof.dump{
            class Hello
              @@var=1
              Const=2
              def world() end
            end
          }
classes
                               Memprof.dump{
                                 class Hello
                                   @@var=1
                                   Const=2
{                                  def world() end
    "_id": "0x19c408",
                                 end
    "type": "class",           }
    "name": "Hello",
    "super": "0x1bfa48",
    "super_name": "Object",

    "ivars": {
       "@@var":   1,
       "Const":   2
    },
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {
       "@@var":   1,
       "Const":   2
    },
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {                 class variables and constants
       "@@var":   1,           are stored in the instance
       "Const":   2
    },                         variable table
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {                 class variables and constants
       "@@var":   1,           are stored in the instance
       "Const":   2
    },                         variable table
    "methods":    {
       "world":   "0x19c318"   references to method objects
    }
}
version 2: analyze data
version 2: memprof.com
   a web-based heap visualizer and leak analyzer
built on...
built on...


    $ mongoimport
        -d memprof
        -c rails
        --file /tmp/app.json
    $ mongo memprof
built on...


    $ mongoimport
        -d memprof
        -c rails
        --file /tmp/app.json
    $ mongo memprof

                 let’s run some queries.
how many objects?
> db.rails.count()
809816

 • ruby scripts create a lot of objects
 • usually not a problem, but...
  • MRI has a naïve stop-the-world mark/
     sweep GC
  • fewer objects = faster GC = better
     performance
what types of objects?
> db.rails.distinct(‘type’)

[‘array’,
 ‘bignum’,
 ‘class’,
 ‘float’,
 ‘hash’,
 ‘module’,
 ‘node’,
 ‘object’,
 ‘regexp’,
 ‘string’,
 ...]
mongodb: distinct
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
•   distinct(‘class_name’)
    list of instance class names
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
•   distinct(‘class_name’)
    list of instance class names
• optionally filter first
    •   distinct(‘name’, {type:“class”})
        names of all defined classes
improve performance
             with indexes

> db.rails.ensureIndex({‘type’:1})
improve performance
             with indexes

> db.rails.ensureIndex({‘type’:1})

> db.rails.ensureIndex(
    {‘file’:1},
    {background:true}
)
mongodb: ensureIndex
• add an index on a field (if it doesn’t exist yet)
• improve performance of queries against
  common fields: type, class_name, super, file
mongodb: ensureIndex
• add an index on a field (if it doesn’t exist yet)
• improve performance of queries against
  common fields: type, class_name, super, file
• can index embedded field names
  •   ensureIndex(‘methods.add’)

  •   find({‘methods.add’:{$exists:true}})
      find classes that define the method add
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
     out.count++
   }
}).sort(function(a,b){
   return a.count - b.count
})
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
                                  increment count
     out.count++
                                  for each obj
   }
}).sort(function(a,b){
   return a.count - b.count
})
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
                                  increment count
     out.count++
                                  for each obj
   }
}).sort(function(a,b){
   return a.count - b.count       sort results
})
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
                                lots of nodes
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
                                        lots of nodes

 • nodes represent ruby code
  • stored like any other ruby object
  • makes ruby completely dynamic
mongodb: group
mongodb: group
• cond: query to filter objects before
  grouping
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
• initial: initial values for each group’s
  results
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
• initial: initial values for each group’s
  results
• reduce: aggregation function
mongodb: group
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
• bycond: in a specific file
     type
 •         {file: “app.rb”},
      key: {file:1, line:1}
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
• bycond: in a specific file
     type
 •         {file: “app.rb”},
      key: {file:1, line:1}

• bycond: {file:“app.rb”,type:‘string’},
     length of strings in a specific file
 •
      key: {length:1}
what subclasses String?
> db.rails.find(
  {super_name:"String"},
  {name:1}
)

{name:   "ActiveSupport::SafeBuffer"}
{name:   "ActiveSupport::StringInquirer"}
{name:   "SQLite3::Blob"}
{name:   "ActiveModel::Name"}
{name:   "Arel::Attribute::Expressions"}
{name:   "ActiveSupport::JSON::Variable"}
what subclasses String?
> db.rails.find(
  {super_name:"String"},
  {name:1}             select only name field
)

{name:   "ActiveSupport::SafeBuffer"}
{name:   "ActiveSupport::StringInquirer"}
{name:   "SQLite3::Blob"}
{name:   "ActiveModel::Name"}
{name:   "Arel::Attribute::Expressions"}
{name:   "ActiveSupport::JSON::Variable"}
mongodb: find
mongodb: find

•   find({type:‘string’})
    all strings
mongodb: find

•   find({type:‘string’})
    all strings
•   find({type:{$ne:‘string’}})
    everything except strings
mongodb: find

•   find({type:‘string’})
    all strings
•   find({type:{$ne:‘string’}})
    everything except strings
•   find({type:‘string’}, {data:1})
    only select string’s data field
the largest objects?
> db.rails.find(
  {type:
     {$in:['string','array','hash']}
  },
  {type:1,length:1}
).sort({length:-1}).limit(3)

{type: "string", length: 2308}
{type: "string", length: 1454}
{type: "string", length: 1238}
mongodb: sort, limit/skip
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
•   limit(10)
    first 10 results
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
•   limit(10)
    first 10 results
•   skip(10).limit(10)
    second 10 results
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
 • create buckets for every
    minute of execution since
    start
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
 • create buckets for every
    minute of execution since
    start
 • place objects into buckets
when were objs created?
> db.rails.mapReduce(function(){
    var secs = this.time - start_time;
    var mins_since_start = secs % 60;
    emit(mins_since_start, 1);
  }, function(key, vals){
    for(var i=0,sum=0; i<vals.length;
        sum += vals[i++]);
    return sum;
  }, {
    scope: { start_time: db.rails.find
().sort({time:1}).limit(1)[0].time }
  }               start_time = min(time)
)
{result:"tmp.mr_1272615772_3"}
mongodb: mapReduce
• arguments
 • map: function that emits one or more
    key/value pairs given each object this
 • reduce: function to return aggregate
    result, given key and list of values
 • scope: global variables to set for funcs
mongodb: mapReduce
• arguments
 • map: function that emits one or more
    key/value pairs given each object this
  • reduce: function to return aggregate
    result, given key and list of values
 • scope: global variables to set for funcs
• results
 • stored in a temporary collection
    (tmp.mr_1272615772_3)
when were objs created?
> db.tmp.mr_1272615772_3.count()
12
                script was running for 12 minutes
when were objs created?
> db.tmp.mr_1272615772_3.count()
12
                  script was running for 12 minutes


> db.tmp.mr_1272615772_3.find().sort
({value:-1}).limit(1)
{_id: 8, value: 41231}
           41k objects created 8 minutes after start
references to this object?
ary = [“a”,”b”,”c”]
                                     ary references “a”
                                 “b” referenced by ary

 • ruby makes it easy to “leak” references
  • an object will stay around until all
     references to it are gone
   • more objects = longer GC = bad
     performance
 • must find references to fix leaks
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
•   db.rails_refs.ensureIndex({refs:1})
    add ‘multikey’ index to refs array
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
•   db.rails_refs.ensureIndex({refs:1})
    add ‘multikey’ index to refs array
•   db.rails_refs.find({refs:“0xa”})
    efficiently lookup all objs holding a ref to 0xa
mongodb: multikeys

• indexes on array values create a ‘multikey’
  index
• classic example: nested array of tags
  •   find({tags: “ruby”})
      find objs where obj.tags includes “ruby”
version 2: memprof.com
   a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
plugging a leak in rails3
• in dev mode, rails3 is leaking 10mb per request
plugging a leak in rails3
• in dev mode, rails3 is leaking 10mb per request

let’s use memprof to find it!

  # in environment.rb
  require `gem which memprof/signal`.strip
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/


 tell memprof to dump
 out the entire heap to
 json
 $ memprof
   --pid <pid>
   --name <dump name>
   --key <api key>
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/


 tell memprof to dump
 out the entire heap to
 json
 $ memprof
   --pid <pid>
   --name <dump name>
   --key <api key>
Debugging Ruby (Aman Gupta)
2519 classes
2519 classes
  30 copies of
TestController
2519 classes
  30 copies of
TestController
2519 classes
  30 copies of
TestController

                 mongo query for all
                 TestController classes
2519 classes
  30 copies of
TestController

                 mongo query for all
                 TestController classes



                 details for one copy of
                 TestController
Debugging Ruby (Aman Gupta)
find references to object
find references to object
find references to object




holding references
 to all controllers
find references to object




 “leak” is on line 178



holding references
 to all controllers
• In development mode, Rails reloads all your
  application code on every request
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• But.. it ends up holding a reference to every single
  reloaded version of those controllers
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• But.. it ends up holding a reference to every single
  reloaded version of those controllers
Questions?
 Aman Gupta
  @tmm1
Ad

More Related Content

What's hot (19)

rails-migrations_1
rails-migrations_1rails-migrations_1
rails-migrations_1
brecke
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
Mike Dirolf
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使う
bpstudy
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolator
Michael Limansky
 
Scala Domain Modeling and Architecture
Scala Domain Modeling and ArchitectureScala Domain Modeling and Architecture
Scala Domain Modeling and Architecture
Hossam Karim
 
Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제
홍준 김
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Library
doughellmann
 
Arrays in PHP
Arrays in PHPArrays in PHP
Arrays in PHP
davidahaskins
 
Spine JS
Spine JSSpine JS
Spine JS
ambientphoto
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
Puneet Behl
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
Uwe Printz
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
Howard Lewis Ship
 
A quick python_tour
A quick python_tourA quick python_tour
A quick python_tour
cghtkh
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
Danilo Sousa
 
Indexing
IndexingIndexing
Indexing
Mike Dirolf
 
Advanced geoprocessing with Python
Advanced geoprocessing with PythonAdvanced geoprocessing with Python
Advanced geoprocessing with Python
Chad Cooper
 
Error based blind sqli
Error based blind sqliError based blind sqli
Error based blind sqli
DarkZtone Zone
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
O T
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDB
Takahiro Inoue
 
rails-migrations_1
rails-migrations_1rails-migrations_1
rails-migrations_1
brecke
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
Mike Dirolf
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使う
bpstudy
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolator
Michael Limansky
 
Scala Domain Modeling and Architecture
Scala Domain Modeling and ArchitectureScala Domain Modeling and Architecture
Scala Domain Modeling and Architecture
Hossam Karim
 
Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제
홍준 김
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Library
doughellmann
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
Puneet Behl
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
Uwe Printz
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
Howard Lewis Ship
 
A quick python_tour
A quick python_tourA quick python_tour
A quick python_tour
cghtkh
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
Danilo Sousa
 
Advanced geoprocessing with Python
Advanced geoprocessing with PythonAdvanced geoprocessing with Python
Advanced geoprocessing with Python
Chad Cooper
 
Error based blind sqli
Error based blind sqliError based blind sqli
Error based blind sqli
DarkZtone Zone
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
O T
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDB
Takahiro Inoue
 

Viewers also liked (20)

Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
Engine Yard
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
Dirkjan Bussink
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby
Aman Gupta
 
OpenSource Hardware -Debian Way
OpenSource Hardware -Debian WayOpenSource Hardware -Debian Way
OpenSource Hardware -Debian Way
Siji Sunny
 
Operating OPNFV
Operating OPNFVOperating OPNFV
Operating OPNFV
OPNFV
 
OpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 MumbaiOpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 Mumbai
Akanksha Agrawal
 
Your first patch to OpenStack
Your first patch to OpenStackYour first patch to OpenStack
Your first patch to OpenStack
openstackindia
 
Copr HD OpenStack Day India
Copr HD OpenStack Day IndiaCopr HD OpenStack Day India
Copr HD OpenStack Day India
openstackindia
 
Deploying openstack using ansible
Deploying openstack using ansibleDeploying openstack using ansible
Deploying openstack using ansible
openstackindia
 
The OpenStack Contribution Workflow
The OpenStack Contribution WorkflowThe OpenStack Contribution Workflow
The OpenStack Contribution Workflow
openstackindia
 
Your first patch to open stack
Your first patch to open stackYour first patch to open stack
Your first patch to open stack
Akanksha Agrawal
 
Open stack qa and tempest
Open stack qa and tempestOpen stack qa and tempest
Open stack qa and tempest
Kamesh Pemmaraju
 
Guts & OpenStack migration
Guts & OpenStack migrationGuts & OpenStack migration
Guts & OpenStack migration
openstackindia
 
OpenStack Storage Buddy Ceph
OpenStack Storage Buddy CephOpenStack Storage Buddy Ceph
OpenStack Storage Buddy Ceph
openstackindia
 
Introduction to tempest
Introduction to tempest Introduction to tempest
Introduction to tempest
openstackindia
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224
Manabu Ori
 
Ryu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic MonitorRyu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic Monitor
jieun kim
 
Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?
Madhuri Kumari
 
OPNFV & OpenStack
OPNFV & OpenStackOPNFV & OpenStack
OPNFV & OpenStack
openstackindia
 
OpenStack Tempest and REST API testing
OpenStack Tempest and REST API testingOpenStack Tempest and REST API testing
OpenStack Tempest and REST API testing
openstackindia
 
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
Engine Yard
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
Dirkjan Bussink
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby
Aman Gupta
 
OpenSource Hardware -Debian Way
OpenSource Hardware -Debian WayOpenSource Hardware -Debian Way
OpenSource Hardware -Debian Way
Siji Sunny
 
Operating OPNFV
Operating OPNFVOperating OPNFV
Operating OPNFV
OPNFV
 
OpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 MumbaiOpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 Mumbai
Akanksha Agrawal
 
Your first patch to OpenStack
Your first patch to OpenStackYour first patch to OpenStack
Your first patch to OpenStack
openstackindia
 
Copr HD OpenStack Day India
Copr HD OpenStack Day IndiaCopr HD OpenStack Day India
Copr HD OpenStack Day India
openstackindia
 
Deploying openstack using ansible
Deploying openstack using ansibleDeploying openstack using ansible
Deploying openstack using ansible
openstackindia
 
The OpenStack Contribution Workflow
The OpenStack Contribution WorkflowThe OpenStack Contribution Workflow
The OpenStack Contribution Workflow
openstackindia
 
Your first patch to open stack
Your first patch to open stackYour first patch to open stack
Your first patch to open stack
Akanksha Agrawal
 
Guts & OpenStack migration
Guts & OpenStack migrationGuts & OpenStack migration
Guts & OpenStack migration
openstackindia
 
OpenStack Storage Buddy Ceph
OpenStack Storage Buddy CephOpenStack Storage Buddy Ceph
OpenStack Storage Buddy Ceph
openstackindia
 
Introduction to tempest
Introduction to tempest Introduction to tempest
Introduction to tempest
openstackindia
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224
Manabu Ori
 
Ryu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic MonitorRyu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic Monitor
jieun kim
 
Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?
Madhuri Kumari
 
OpenStack Tempest and REST API testing
OpenStack Tempest and REST API testingOpenStack Tempest and REST API testing
OpenStack Tempest and REST API testing
openstackindia
 
Ad

Similar to Debugging Ruby (Aman Gupta) (20)

Presentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStackPresentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStack
David Sanchez
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
MongoDB
 
Forking Oryx at Intalio
Forking Oryx at IntalioForking Oryx at Intalio
Forking Oryx at Intalio
Antoine Toulme
 
Struktur data 1
Struktur data 1Struktur data 1
Struktur data 1
bagus dwi saputra
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
OSU Open Source Lab
 
The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212
Mahmoud Samir Fayed
 
Webinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible SchemasWebinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible Schemas
MongoDB
 
Mongo db presentation
Mongo db presentationMongo db presentation
Mongo db presentation
Julie Sommerville
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
CouchDB-Lucene
CouchDB-LuceneCouchDB-Lucene
CouchDB-Lucene
Martin Rehfeld
 
Latinoware
LatinowareLatinoware
Latinoware
kchodorow
 
Strongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible SchemasStrongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible Schemas
Norberto Leite
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
UC San Diego
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlin
Toshiaki Katayama
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
Mike Dirolf
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
Aleksandar Veselinovic
 
Net framework
Net frameworkNet framework
Net framework
Abhishek Mukherjee
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wrangling
jakehofman
 
SVGo workshop
SVGo workshopSVGo workshop
SVGo workshop
Anthony Starks
 
Presentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStackPresentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStack
David Sanchez
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
MongoDB
 
Forking Oryx at Intalio
Forking Oryx at IntalioForking Oryx at Intalio
Forking Oryx at Intalio
Antoine Toulme
 
The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212
Mahmoud Samir Fayed
 
Webinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible SchemasWebinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible Schemas
MongoDB
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
Strongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible SchemasStrongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible Schemas
Norberto Leite
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
UC San Diego
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlin
Toshiaki Katayama
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
Mike Dirolf
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wrangling
jakehofman
 
Ad

More from MongoSF (19)

Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
MongoSF
 
Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)
MongoSF
 
C# Development (Sam Corder)
C# Development (Sam Corder)C# Development (Sam Corder)
C# Development (Sam Corder)
MongoSF
 
Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)
MongoSF
 
Administration (Eliot Horowitz)
Administration (Eliot Horowitz)Administration (Eliot Horowitz)
Administration (Eliot Horowitz)
MongoSF
 
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoSF
 
Administration
AdministrationAdministration
Administration
MongoSF
 
Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)
MongoSF
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
MongoSF
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)
MongoSF
 
Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)
MongoSF
 
MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)
MongoSF
 
Zero to Mongo in 60 Hours
Zero to Mongo in 60 HoursZero to Mongo in 60 Hours
Zero to Mongo in 60 Hours
MongoSF
 
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
MongoSF
 
PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)
MongoSF
 
Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)
MongoSF
 
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
MongoSF
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)
MongoSF
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
MongoSF
 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
MongoSF
 
Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)
MongoSF
 
C# Development (Sam Corder)
C# Development (Sam Corder)C# Development (Sam Corder)
C# Development (Sam Corder)
MongoSF
 
Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)
MongoSF
 
Administration (Eliot Horowitz)
Administration (Eliot Horowitz)Administration (Eliot Horowitz)
Administration (Eliot Horowitz)
MongoSF
 
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoSF
 
Administration
AdministrationAdministration
Administration
MongoSF
 
Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)
MongoSF
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
MongoSF
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)
MongoSF
 
Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)
MongoSF
 
MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)
MongoSF
 
Zero to Mongo in 60 Hours
Zero to Mongo in 60 HoursZero to Mongo in 60 Hours
Zero to Mongo in 60 Hours
MongoSF
 
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
MongoSF
 
PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)
MongoSF
 
Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)
MongoSF
 
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
MongoSF
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)
MongoSF
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
MongoSF
 

Recently uploaded (20)

Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 

Debugging Ruby (Aman Gupta)

  • 1. Debugging Ruby with MongoDB Aman Gupta @tmm1
  • 3. debugging ruby? • i use ruby • my ruby processes use a lot of ram
  • 4. debugging ruby? • i use ruby • my ruby processes use a lot of ram • i want to fix this
  • 5. let’s build a debugger • step 1: collect data • list of all ruby objects in memory
  • 6. let’s build a debugger • step 1: collect data • list of all ruby objects in memory • step 2: analyze data • group by type • group by file/line
  • 7. version 1: collect data • simple patch to ruby VM (300 lines of C) • http://gist.github.com/73674 • simple text based output format 0x154750 @ -e:1 is OBJECT of type: T 0x15476c @ -e:1 is HASH which has data 0x154788 @ -e:1 is ARRAY of len: 0 0x1547c0 @ -e:1 is STRING (SHARED) len: 2 and val: hi 0x1547dc @ -e:1 is STRING len: 1 and val: T 0x154814 @ -e:1 is CLASS named: T inherits from Object 0x154a98 @ -e:1 is STRING len: 2 and val: hi 0x154b40 @ -e:1 is OBJECT of type: Range
  • 8. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap
  • 9. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap $ cat /tmp/ruby.heap | awk '{ print $3 }' | sort | uniq -c | sort -g | tail -1  236840 memcached/memcached.rb:316
  • 10. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap $ cat /tmp/ruby.heap | awk '{ print $3 }' | sort | uniq -c | sort -g | tail -1  236840 memcached/memcached.rb:316 $ grep "memcached.rb:316" /tmp/ruby.heap | awk '{ print $5 }' | sort | uniq -c | sort -g | tail -5    10948 ARRAY    20355 OBJECT    30744 DATA   64952 HASH   123290 STRING
  • 13. version 1 • it works! • but...
  • 14. version 1 • it works! • but... • must patch and rebuild ruby binary
  • 15. version 1 • it works! • but... • must patch and rebuild ruby binary • no information about references between objects
  • 16. version 1 • it works! • but... • must patch and rebuild ruby binary • no information about references between objects • limited analysis via shell scripting
  • 18. version 2 goals • better data format
  • 19. version 2 goals • better data format • simple: one line of text per object
  • 20. version 2 goals • better data format • simple: one line of text per object • expressive: include all details about object contents and references
  • 21. version 2 goals • better data format • simple: one line of text per object • expressive: include all details about object contents and references • easy to use: easy to generate from C code & easy to consume from various scripting languages
  • 22. JSON!
  • 23. version 2 is memprof
  • 24. version 2 is memprof • no patches to ruby necessary • gem install memprof • require ‘memprof’ • Memprof.dump_all(“/tmp/app.json”)
  • 25. version 2 is memprof • no patches to ruby necessary • gem install memprof • require ‘memprof’ • Memprof.dump_all(“/tmp/app.json”) • C extension for MRI ruby VM http://github.com/ice799/memprof • uses libyajl to dump out all ruby objects as json
  • 26. Memprof.dump{ strings } “hello” + “world”
  • 27. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", "line": 1, "type": "string", "class": "0x1ba7f0", "class_name": "String", "length": 10, "data": "helloworld" }
  • 28. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", "class_name": "String", "length": 10, "data": "helloworld" }
  • 29. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", address of the class object "class_name": "String", “String” "length": 10, "data": "helloworld" }
  • 30. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", address of the class object "class_name": "String", “String” "length": 10, length and contents "data": "helloworld" of this string instance }
  • 31. arrays Memprof.dump{ [ 1, :b, 2.2, “d” ] }
  • 32. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, ":b", "0x19c750", "0x19c598" ] }
  • 33. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, integers and symbols are ":b", stored in the array itself "0x19c750", "0x19c598" ] }
  • 34. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, integers and symbols are ":b", stored in the array itself "0x19c750", floats and strings are "0x19c598" separate ruby objects ] }
  • 35. hashes Memprof.dump{ { :a => 1, “b” => 2.2 } }
  • 36. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, "length": 2, "data": [ [ ":a", 1 ], [ "0xc728", "0xc750" ] ] }
  • 37. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, "length": 2, "data": [ [ ":a", 1 ], hash entries as key/value [ "0xc728", "0xc750" ] pairs ] }
  • 38. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, no default proc "length": 2, "data": [ [ ":a", 1 ], hash entries as key/value [ "0xc728", "0xc750" ] pairs ] }
  • 39. classes Memprof.dump{ class Hello @@var=1 Const=2 def world() end end }
  • 40. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", "super_name": "Object", "ivars": { "@@var": 1, "Const": 2 }, "methods": { "world": "0x19c318" } }
  • 41. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { "@@var": 1, "Const": 2 }, "methods": { "world": "0x19c318" } }
  • 42. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { class variables and constants "@@var": 1, are stored in the instance "Const": 2 }, variable table "methods": { "world": "0x19c318" } }
  • 43. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { class variables and constants "@@var": 1, are stored in the instance "Const": 2 }, variable table "methods": { "world": "0x19c318" references to method objects } }
  • 45. version 2: memprof.com a web-based heap visualizer and leak analyzer
  • 47. built on... $ mongoimport -d memprof -c rails --file /tmp/app.json $ mongo memprof
  • 48. built on... $ mongoimport -d memprof -c rails --file /tmp/app.json $ mongo memprof let’s run some queries.
  • 49. how many objects? > db.rails.count() 809816 • ruby scripts create a lot of objects • usually not a problem, but... • MRI has a naïve stop-the-world mark/ sweep GC • fewer objects = faster GC = better performance
  • 50. what types of objects? > db.rails.distinct(‘type’) [‘array’, ‘bignum’, ‘class’, ‘float’, ‘hash’, ‘module’, ‘node’, ‘object’, ‘regexp’, ‘string’, ...]
  • 52. mongodb: distinct • distinct(‘type’) list of types of objects
  • 53. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files
  • 54. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files • distinct(‘class_name’) list of instance class names
  • 55. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files • distinct(‘class_name’) list of instance class names • optionally filter first • distinct(‘name’, {type:“class”}) names of all defined classes
  • 56. improve performance with indexes > db.rails.ensureIndex({‘type’:1})
  • 57. improve performance with indexes > db.rails.ensureIndex({‘type’:1}) > db.rails.ensureIndex( {‘file’:1}, {background:true} )
  • 58. mongodb: ensureIndex • add an index on a field (if it doesn’t exist yet) • improve performance of queries against common fields: type, class_name, super, file
  • 59. mongodb: ensureIndex • add an index on a field (if it doesn’t exist yet) • improve performance of queries against common fields: type, class_name, super, file • can index embedded field names • ensureIndex(‘methods.add’) • find({‘methods.add’:{$exists:true}}) find classes that define the method add
  • 60. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { out.count++ } }).sort(function(a,b){ return a.count - b.count })
  • 61. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { increment count out.count++ for each obj } }).sort(function(a,b){ return a.count - b.count })
  • 62. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { increment count out.count++ for each obj } }).sort(function(a,b){ return a.count - b.count sort results })
  • 63. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ]
  • 64. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ] lots of nodes
  • 65. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ] lots of nodes • nodes represent ruby code • stored like any other ruby object • makes ruby completely dynamic
  • 67. mongodb: group • cond: query to filter objects before grouping
  • 68. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on
  • 69. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on • initial: initial values for each group’s results
  • 70. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on • initial: initial values for each group’s results • reduce: aggregation function
  • 72. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1}
  • 73. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line •
  • 74. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line • • bycond: in a specific file type • {file: “app.rb”}, key: {file:1, line:1}
  • 75. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line • • bycond: in a specific file type • {file: “app.rb”}, key: {file:1, line:1} • bycond: {file:“app.rb”,type:‘string’}, length of strings in a specific file • key: {length:1}
  • 76. what subclasses String? > db.rails.find( {super_name:"String"}, {name:1} ) {name: "ActiveSupport::SafeBuffer"} {name: "ActiveSupport::StringInquirer"} {name: "SQLite3::Blob"} {name: "ActiveModel::Name"} {name: "Arel::Attribute::Expressions"} {name: "ActiveSupport::JSON::Variable"}
  • 77. what subclasses String? > db.rails.find( {super_name:"String"}, {name:1} select only name field ) {name: "ActiveSupport::SafeBuffer"} {name: "ActiveSupport::StringInquirer"} {name: "SQLite3::Blob"} {name: "ActiveModel::Name"} {name: "Arel::Attribute::Expressions"} {name: "ActiveSupport::JSON::Variable"}
  • 79. mongodb: find • find({type:‘string’}) all strings
  • 80. mongodb: find • find({type:‘string’}) all strings • find({type:{$ne:‘string’}}) everything except strings
  • 81. mongodb: find • find({type:‘string’}) all strings • find({type:{$ne:‘string’}}) everything except strings • find({type:‘string’}, {data:1}) only select string’s data field
  • 82. the largest objects? > db.rails.find( {type: {$in:['string','array','hash']} }, {type:1,length:1} ).sort({length:-1}).limit(3) {type: "string", length: 2308} {type: "string", length: 1454} {type: "string", length: 1238}
  • 84. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc
  • 85. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc • limit(10) first 10 results
  • 86. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc • limit(10) first 10 results • skip(10).limit(10) second 10 results
  • 87. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created
  • 88. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time
  • 89. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time • create buckets for every minute of execution since start
  • 90. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time • create buckets for every minute of execution since start • place objects into buckets
  • 91. when were objs created? > db.rails.mapReduce(function(){ var secs = this.time - start_time; var mins_since_start = secs % 60; emit(mins_since_start, 1); }, function(key, vals){ for(var i=0,sum=0; i<vals.length; sum += vals[i++]); return sum; }, { scope: { start_time: db.rails.find ().sort({time:1}).limit(1)[0].time } } start_time = min(time) ) {result:"tmp.mr_1272615772_3"}
  • 92. mongodb: mapReduce • arguments • map: function that emits one or more key/value pairs given each object this • reduce: function to return aggregate result, given key and list of values • scope: global variables to set for funcs
  • 93. mongodb: mapReduce • arguments • map: function that emits one or more key/value pairs given each object this • reduce: function to return aggregate result, given key and list of values • scope: global variables to set for funcs • results • stored in a temporary collection (tmp.mr_1272615772_3)
  • 94. when were objs created? > db.tmp.mr_1272615772_3.count() 12 script was running for 12 minutes
  • 95. when were objs created? > db.tmp.mr_1272615772_3.count() 12 script was running for 12 minutes > db.tmp.mr_1272615772_3.find().sort ({value:-1}).limit(1) {_id: 8, value: 41231} 41k objects created 8 minutes after start
  • 96. references to this object? ary = [“a”,”b”,”c”] ary references “a” “b” referenced by ary • ruby makes it easy to “leak” references • an object will stay around until all references to it are gone • more objects = longer GC = bad performance • must find references to fix leaks
  • 97. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table
  • 98. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table • db.rails_refs.ensureIndex({refs:1}) add ‘multikey’ index to refs array
  • 99. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table • db.rails_refs.ensureIndex({refs:1}) add ‘multikey’ index to refs array • db.rails_refs.find({refs:“0xa”}) efficiently lookup all objs holding a ref to 0xa
  • 100. mongodb: multikeys • indexes on array values create a ‘multikey’ index • classic example: nested array of tags • find({tags: “ruby”}) find objs where obj.tags includes “ruby”
  • 101. version 2: memprof.com a web-based heap visualizer and leak analyzer
  • 102. memprof.com a web-based heap visualizer and leak analyzer
  • 103. memprof.com a web-based heap visualizer and leak analyzer
  • 104. memprof.com a web-based heap visualizer and leak analyzer
  • 105. memprof.com a web-based heap visualizer and leak analyzer
  • 106. memprof.com a web-based heap visualizer and leak analyzer
  • 107. memprof.com a web-based heap visualizer and leak analyzer
  • 108. memprof.com a web-based heap visualizer and leak analyzer
  • 109. memprof.com a web-based heap visualizer and leak analyzer
  • 110. memprof.com a web-based heap visualizer and leak analyzer
  • 111. plugging a leak in rails3 • in dev mode, rails3 is leaking 10mb per request
  • 112. plugging a leak in rails3 • in dev mode, rails3 is leaking 10mb per request let’s use memprof to find it! # in environment.rb require `gem which memprof/signal`.strip
  • 113. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/
  • 114. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/ tell memprof to dump out the entire heap to json $ memprof --pid <pid> --name <dump name> --key <api key>
  • 115. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/ tell memprof to dump out the entire heap to json $ memprof --pid <pid> --name <dump name> --key <api key>
  • 118. 2519 classes 30 copies of TestController
  • 119. 2519 classes 30 copies of TestController
  • 120. 2519 classes 30 copies of TestController mongo query for all TestController classes
  • 121. 2519 classes 30 copies of TestController mongo query for all TestController classes details for one copy of TestController
  • 125. find references to object holding references to all controllers
  • 126. find references to object “leak” is on line 178 holding references to all controllers
  • 127. • In development mode, Rails reloads all your application code on every request
  • 128. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization
  • 129. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization • But.. it ends up holding a reference to every single reloaded version of those controllers
  • 130. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization • But.. it ends up holding a reference to every single reloaded version of those controllers