Slide 1

Slide 1 text

CACHING MARSHAL Chris Salzberg Without Without

Slide 2

Slide 2 text

Chris Salzberg @shioyama Staff Dev @ Ruby & Rails Infra Team: Core Stewardship

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

before After

Slide 5

Slide 5 text

before After cache

Slide 6

Slide 6 text

let’s talk about caching caching

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

I CAN CACHE ALL THE THINGS

Slide 10

Slide 10 text

Rails.cache.write(...)

Slide 11

Slide 11 text

# activesupport/lib/active_support/cache.rb # module Rails70Coder include Loader extend self def dump(entry) MARK_70_UNCOMPRESSED + Marshal.dump(entry.pack) end def dump_compressed(entry, threshold) payload = Marshal.dump(entry.pack) # ... MARK_70_UNCOMPRESSED + payload end

Slide 12

Slide 12 text

value expires_at version expires_at version ActiveSupport::Cache::Entry C compression bit < Rails 7 ≥ Rails 7 ActiveSupport::Cache::Entry value Marshal-encoded Marshal-encoded

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

irb(main):010:0> Marshal.method(:dump).source

Slide 16

Slide 16 text

irb(main):010:0> Marshal.method(:dump).source Could not locate source for dump! (MethodSource::SourceNotFoundError)

Slide 17

Slide 17 text

let’s talk about Marshal Marshal

Slide 18

Slide 18 text

class Post < ApplicationRecord end

Slide 19

Slide 19 text

post = Post.create(title: "Caching Without Marshal") #=> #

Slide 20

Slide 20 text

post = Post.create(title: "Caching Without Marshal") #=> #

Slide 21

Slide 21 text

1607 bytes!!! post = Post.create(title: "Caching Without Marshal") #=> # "\x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::AttributeSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveMod el::Attribute::FromDatabase\n:\n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::ConnectionAdapters::SQLite3Ad apter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00 \x80:\bendl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1C Caching Without Marshal\x06;\tT;\ro:\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06;\tT;\x0F0;\x10 0;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ActiveSupport::TimeWithZon e[\bIu:\tTime\re\x8F\x1E\xC0\xA7\x88\x83\x02\x06:\tzoneI\"\bUTC\x06;\tFI\"\bUTC\x06;\tTIu;\x1D\re\x8F\x1E\xC0\xA7\x88\x83\x02\x 06;\x1E@\x19;\rU:JActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter[\t:\v__v2__[\x00[\x00o:!ActiveRecord::T ype::DateTime\b;\x0Fi\v;\x100;\x110;\x170;\x18@\x17I\"\x0Fupdated_at\x06;\tTo;\n\n;\v@\";\fU;\x1C[\b@\x1A@\eIu;\x1D\re\x8F\x1E\ xC0\xA7\x88\x83\x02\x06;\x1E@\x19;\rU;\x1F[\t; [\x00[\x00@!;\x170;\x18@$:\x17@association_cache{\x00:\x0E@readonlyF:\e@previous ly_new_recordT:\x0F@destroyedF:\x1C@marked_for_destructionF:\x1E@destroyed_by_association0:\x1E@_start_transaction_state0:\x11@ primary_key@\b:\x14@strict_loadingF:\x19@strict_loading_mode:\ball:$@_new_record_before_last_commitT:\x18@validation_context0:\ f@errorso:\x18ActiveModel::Errors\a:\n@base@\x00;/[\x00:\x13@_touch_recordT:\x1D@mutations_from_database0: @mutations_before_la st_saveo:*ActiveModel::AttributeMutationTracker\x06;\ao;\b\x06;\a{\t@\bo:%ActiveModel::Attribute::FromUser\n;\v@\b;\fi\x06;\r@\ n;\x17o;\n\n;\v@\b;\f0;\r@\n;\x170;\x180;\x18i\x06@\x0Eo;6\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\r@\x11;\x17o;\n\ t;\v@\x0E;\f0;\r@\x11;\x170;\x18@\x10@\x15o;6\n;\v@\x15;\f@\x1A;\r@\x1D;\x17o;\n\n;\v@\x15;\f0;\r@\x1D;\x170;\x180;\x18@\x17@\" o;6\n;\v@\";\f@\x1A;\r@';\x17o;\n\n;\v@\";\f0;\r@';\x170;\x180;\x18@$:\x1F@_committed_already_calledF:\x1F@_trigger_destroy_cal lbackF:\x1E@_trigger_update_callbackF"

Slide 22

Slide 22 text

post = Post.create(title: "Caching Without Marshal") #=> # "\x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::AttributeSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveMod el::Attribute::FromDatabase\n:\n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::ConnectionAdapters::SQLite3Ad apter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00 \x80:\bendl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1C Caching Without Marshal\x06;\tT;\ro:\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06;\tT;\x0F0;\x10 0;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ActiveSupport::TimeWithZon e[\bIu:\tTime\re\x8F\x1E\xC0\xA7\x88\x83\x02\x06:\tzoneI\"\bUTC\x06;\tFI\"\bUTC\x06;\tTIu;\x1D\re\x8F\x1E\xC0\xA7\x88\x83\x02\x 06;\x1E@\x19;\rU:JActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter[\t:\v__v2__[\x00[\x00o:!ActiveRecord::T ype::DateTime\b;\x0Fi\v;\x100;\x110;\x170;\x18@\x17I\"\x0Fupdated_at\x06;\tTo;\n\n;\v@\";\fU;\x1C[\b@\x1A@\eIu;\x1D\re\x8F\x1E\ xC0\xA7\x88\x83\x02\x06;\x1E@\x19;\rU;\x1F[\t; [\x00[\x00@!;\x170;\x18@$:\x17@association_cache{\x00:\x0E@readonlyF:\e@previous ly_new_recordT:\x0F@destroyedF:\x1C@marked_for_destructionF:\x1E@destroyed_by_association0:\x1E@_start_transaction_state0:\x11@ primary_key@\b:\x14@strict_loadingF:\x19@strict_loading_mode:\ball:$@_new_record_before_last_commitT:\x18@validation_context0:\ f@errorso:\x18ActiveModel::Errors\a:\n@base@\x00;/[\x00:\x13@_touch_recordT:\x1D@mutations_from_database0: @mutations_before_la st_saveo:*ActiveModel::AttributeMutationTracker\x06;\ao;\b\x06;\a{\t@\bo:%ActiveModel::Attribute::FromUser\n;\v@\b;\fi\x06;\r@\ n;\x17o;\n\n;\v@\b;\f0;\r@\n;\x170;\x180;\x18i\x06@\x0Eo;6\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\r@\x11;\x17o;\n\ t;\v@\x0E;\f0;\r@\x11;\x170;\x18@\x10@\x15o;6\n;\v@\x15;\f@\x1A;\r@\x1D;\x17o;\n\n;\v@\x15;\f0;\r@\x1D;\x170;\x180;\x18@\x17@\" o;6\n;\v@\";\f@\x1A;\r@';\x17o;\n\n;\v@\";\f0;\r@';\x170;\x180;\x18@$:\x1F@_committed_already_calledF:\x1F@_trigger_destroy_cal lbackF:\x1E@_trigger_update_callbackF" Constants

Slide 23

Slide 23 text

post = Post.create(title: "Caching Without Marshal") #=> # "\x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::AttributeSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveMod el::Attribute::FromDatabase\n:\n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::ConnectionAdapters::SQLite3Ad apter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00 \x80:\bendl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1C Caching Without Marshal\x06;\tT;\ro:\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06;\tT;\x0F0;\x10 0;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ActiveSupport::TimeWithZon e[\bIu:\tTime\re\x8F\x1E\xC0\xA7\x88\x83\x02\x06:\tzoneI\"\bUTC\x06;\tFI\"\bUTC\x06;\tTIu;\x1D\re\x8F\x1E\xC0\xA7\x88\x83\x02\x 06;\x1E@\x19;\rU:JActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter[\t:\v__v2__[\x00[\x00o:!ActiveRecord::T ype::DateTime\b;\x0Fi\v;\x100;\x110;\x170;\x18@\x17I\"\x0Fupdated_at\x06;\tTo;\n\n;\v@\";\fU;\x1C[\b@\x1A@\eIu;\x1D\re\x8F\x1E\ xC0\xA7\x88\x83\x02\x06;\x1E@\x19;\rU;\x1F[\t; [\x00[\x00@!;\x170;\x18@$:\x17@association_cache{\x00:\x0E@readonlyF:\e@previous ly_new_recordT:\x0F@destroyedF:\x1C@marked_for_destructionF:\x1E@destroyed_by_association0:\x1E@_start_transaction_state0:\x11@ primary_key@\b:\x14@strict_loadingF:\x19@strict_loading_mode:\ball:$@_new_record_before_last_commitT:\x18@validation_context0:\ f@errorso:\x18ActiveModel::Errors\a:\n@base@\x00;/[\x00:\x13@_touch_recordT:\x1D@mutations_from_database0: @mutations_before_la st_saveo:*ActiveModel::AttributeMutationTracker\x06;\ao;\b\x06;\a{\t@\bo:%ActiveModel::Attribute::FromUser\n;\v@\b;\fi\x06;\r@\ n;\x17o;\n\n;\v@\b;\f0;\r@\n;\x170;\x180;\x18i\x06@\x0Eo;6\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\r@\x11;\x17o;\n\ t;\v@\x0E;\f0;\r@\x11;\x170;\x18@\x10@\x15o;6\n;\v@\x15;\f@\x1A;\r@\x1D;\x17o;\n\n;\v@\x15;\f0;\r@\x1D;\x170;\x180;\x18@\x17@\" o;6\n;\v@\";\f@\x1A;\r@';\x17o;\n\n;\v@\";\f0;\r@';\x170;\x180;\x18@$:\x1F@_committed_already_calledF:\x1F@_trigger_destroy_cal lbackF:\x1E@_trigger_update_callbackF" ivars

Slide 24

Slide 24 text

post = Post.create(title: "Caching Without Marshal") #=> # "\x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::AttributeSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveMod el::Attribute::FromDatabase\n:\n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::ConnectionAdapters::SQLite3Ad apter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00 \x80:\bendl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1C Caching Without Marshal\x06;\tT;\ro:\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06;\tT;\x0F0;\x10 0;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ActiveSupport::TimeWithZon e[\bIu:\tTime\re\x8F\x1E\xC0\xA7\x88\x83\x02\x06:\tzoneI\"\bUTC\x06;\tFI\"\bUTC\x06;\tTIu;\x1D\re\x8F\x1E\xC0\xA7\x88\x83\x02\x 06;\x1E@\x19;\rU:JActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter[\t:\v__v2__[\x00[\x00o:!ActiveRecord::T ype::DateTime\b;\x0Fi\v;\x100;\x110;\x170;\x18@\x17I\"\x0Fupdated_at\x06;\tTo;\n\n;\v@\";\fU;\x1C[\b@\x1A@\eIu;\x1D\re\x8F\x1E\ xC0\xA7\x88\x83\x02\x06;\x1E@\x19;\rU;\x1F[\t; [\x00[\x00@!;\x170;\x18@$:\x17@association_cache{\x00:\x0E@readonlyF:\e@previous ly_new_recordT:\x0F@destroyedF:\x1C@marked_for_destructionF:\x1E@destroyed_by_association0:\x1E@_start_transaction_state0:\x11@ primary_key@\b:\x14@strict_loadingF:\x19@strict_loading_mode:\ball:$@_new_record_before_last_commitT:\x18@validation_context0:\ f@errorso:\x18ActiveModel::Errors\a:\n@base@\x00;/[\x00:\x13@_touch_recordT:\x1D@mutations_from_database0: @mutations_before_la st_saveo:*ActiveModel::AttributeMutationTracker\x06;\ao;\b\x06;\a{\t@\bo:%ActiveModel::Attribute::FromUser\n;\v@\b;\fi\x06;\r@\ n;\x17o;\n\n;\v@\b;\f0;\r@\n;\x170;\x180;\x18i\x06@\x0Eo;6\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\r@\x11;\x17o;\n\ t;\v@\x0E;\f0;\r@\x11;\x170;\x18@\x10@\x15o;6\n;\v@\x15;\f@\x1A;\r@\x1D;\x17o;\n\n;\v@\x15;\f0;\r@\x1D;\x170;\x180;\x18@\x17@\" o;6\n;\v@\";\f@\x1A;\r@';\x17o;\n\n;\v@\";\f0;\r@';\x170;\x180;\x18@$:\x1F@_committed_already_calledF:\x1F@_trigger_destroy_cal lbackF:\x1E@_trigger_update_callbackF" Values

Slide 25

Slide 25 text

post = Post.create(title: "Caching Without Marshal") #=> # #

Slide 26

Slide 26 text

marshal encodes the universe the universe

Slide 27

Slide 27 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U'

Slide 28

Slide 28 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U'

Slide 29

Slide 29 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic

Slide 30

Slide 30 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 31

Slide 31 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 32

Slide 32 text

Objects Objects

Slide 33

Slide 33 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 34

Slide 34 text

\x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::Attribu teSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveModel::Attribute::FromDatabase\n:\ n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::Connection Adapters::SQLite3Adapter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit 0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00\x80:\be ndl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06 I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\ro :\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06 ;\tT;\x0F0;\x100;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0 Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ...

Slide 35

Slide 35 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a... \x04\bo:\tPost\x1A:\x10@new_recordF:\x10@attributeso:\x1EActiveModel::Attribu teSet\x06;\a{\tI\"\aid\x06:\x06ETo:)ActiveModel::Attribute::FromDatabase\n:\ n@name@\b:\x1C@value_before_type_casti\x06:\n@typeo:EActiveRecord::Connection Adapters::SQLite3Adapter::SQLite3Integer\t:\x0F@precision0:\v@scale0:\v@limit 0:\v@rangeo:\nRange\b:\texclT:\nbeginl-\t\x00\x00\x00\x00\x00\x00\x00\x80:\be ndl+\t\x00\x00\x00\x00\x00\x00\x00\x80:\x18@original_attribute0:\v@valuei\x06 I\"\ntitle\x06;\tTo;\n\n;\v@\x0E;\fI\"\x1CCaching Without Marshal\x06;\tT;\ro :\x1EActiveModel::Type::String\n:\n@trueI\"\x06t\x06;\tT:\v@falseI\"\x06f\x06 ;\tT;\x0F0;\x100;\x110;\x170;\x18I\"\x1CCaching Without Marshal\x06;\tTI\"\x0 Fcreated_at\x06;\tTo;\n\n;\v@\x15;\fU: ...

Slide 36

Slide 36 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a... Version

Slide 37

Slide 37 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a... o : length o s t P number of ivars

Slide 38

Slide 38 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a... : length @new_record

Slide 39

Slide 39 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a... F

Slide 40

Slide 40 text

0408 6f3a 0950 6f73 741a 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a...

Slide 41

Slide 41 text

variables variables

Slide 42

Slide 42 text

mystring = "Caching Without Marshal"

Slide 43

Slide 43 text

mystring = "Caching Without Marshal" mystring.instance_variable_set(:@hidden, true) mystring.instance_variable_get(:@hidden) #=> true

Slide 44

Slide 44 text

mystring = "Caching Without Marshal" mystring.instance_variable_set(:@hidden, true) mystring.instance_variable_get(:@hidden) #=> true encoded = Marshal.dump(mystring) decoded = Marshal.load(encoded) decoded.instance_variable_get(:@hidden) #=> ???

Slide 45

Slide 45 text

mystring = "Caching Without Marshal" mystring.instance_variable_set(:@hidden, true) mystring.instance_variable_get(:@hidden) #=> true encoded = Marshal.dump(mystring) decoded = Marshal.load(encoded) decoded.instance_variable_get(:@hidden) #=> true

Slide 46

Slide 46 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 47

Slide 47 text

links links

Slide 48

Slide 48 text

myarray = []

Slide 49

Slide 49 text

myarray = [] myarray << myarray #=> [[...]]

Slide 50

Slide 50 text

myarray = [] myarray << myarray #=> [[...]] decoded = Marshal.load(Marshal.dump(myarray)) #=> ???

Slide 51

Slide 51 text

myarray = [] myarray << myarray #=> [[...]] decoded = Marshal.load(Marshal.dump(myarray)) #=> [[...]]

Slide 52

Slide 52 text

myarray = [] myarray << myarray #=> [[...]] decoded = Marshal.load(Marshal.dump(myarray)) #=> [[...]] decoded.first == decoded #=> true

Slide 53

Slide 53 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 54

Slide 54 text

0408 5b06 4000

Slide 55

Slide 55 text

0408 5b06 4000 [ length TYPE_ARRAY

Slide 56

Slide 56 text

0408 5b06 4000 [ length @ position TYPE_LINK

Slide 57

Slide 57 text

core type core type subclasses subclasses

Slide 58

Slide 58 text

class MyHash < Hash end

Slide 59

Slide 59 text

class MyHash < Hash end my_hash = MyHash.new #=> {}

Slide 60

Slide 60 text

class MyHash < Hash end my_hash = MyHash.new my_hash.class #=> MyHash

Slide 61

Slide 61 text

class MyHash < Hash end my_hash = MyHash.new encoded = Marshal.dump(my_hash) decoded = Marshal.load(encoded) #=> {}

Slide 62

Slide 62 text

class MyHash < Hash end my_hash = MyHash.new encoded = Marshal.dump(my_hash) decoded = Marshal.load(encoded) decoded.class #=> MyHash

Slide 63

Slide 63 text

marshal.c #define MARSHAL_MAJOR 4 #define MARSHAL_MINOR 8 #define TYPE_NIL '0' #define TYPE_TRUE 'T' #define TYPE_FALSE 'F' #define TYPE_FIXNUM 'i' #define TYPE_BIGNUM 'l' #define TYPE_FLOAT 'f' #define TYPE_SYMBOL ':' #define TYPE_CLASS 'c' #define TYPE_MODULE 'm' #define TYPE_LINK '@' #define TYPE_SYMLINK ';' #define TYPE_STRING '"' #define TYPE_REGEXP '/' #define TYPE_ARRAY '[' #define TYPE_HASH '{' #define TYPE_HASH_DEF '}' #define TYPE_STRUCT 'S' #define TYPE_OBJECT 'o' #define TYPE_IVAR 'I' #define TYPE_UCLASS 'C' #define TYPE_EXTENDED 'e' #define TYPE_USERDEF 'u' #define TYPE_USRMARSHAL 'U' atomic composite

Slide 64

Slide 64 text

MARSHAL MARSHAL RAILS DEVELOPER RAILS DEVELOPER

Slide 65

Slide 65 text

let’s talk about what we did what we did

Slide 66

Slide 66 text

before After cache

Slide 67

Slide 67 text

before After

Slide 68

Slide 68 text

We need a format that does not encode the universe.

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

encoded = MessagePack.pack({"foo" => "bar"})

Slide 72

Slide 72 text

encoded = MessagePack.pack({"foo" => "bar"}) => "\x81\xA3foo\xA3bar"

Slide 73

Slide 73 text

encoded = MessagePack.pack({"foo" => "bar"}) => "\x81\xA3foo\xA3bar" decoded = MessagePack.unpack(encoded) => {"foo"=>"bar"}

Slide 74

Slide 74 text

Core Types

Slide 75

Slide 75 text

Core Types atomic

Slide 76

Slide 76 text

Core Types composite

Slide 77

Slide 77 text

Core Types No Object Type

Slide 78

Slide 78 text

Core Types No Object Type No ivar Type

Slide 79

Slide 79 text

0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo")

Slide 80

Slide 80 text

0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo") foo " length 3

Slide 81

Slide 81 text

0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo") :E TYPE_IVAR length 1 T “This string’s encoding is UTF-8.”

Slide 82

Slide 82 text

a366 6f6f MessagePack.pack("foo")

Slide 83

Slide 83 text

a366 6f6f MessagePack.pack("foo") foo

Slide 84

Slide 84 text

a366 6f6f MessagePack.pack("foo") foo (String type encoding is UTF-8.)

Slide 85

Slide 85 text

a366 6f6f MessagePack.pack("foo") 10100011 string of length < 31 bytes

Slide 86

Slide 86 text

a366 6f6f MessagePack.pack("foo") 10100011 length 3

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

ActiveRecord::Base

Slide 89

Slide 89 text

Object?

Slide 90

Slide 90 text

We need a format that does not encode the universe. whole ^

Slide 91

Slide 91 text

We need a format that does not encode the universe. (but let’s us encode parts of it) whole ^

Slide 92

Slide 92 text

factory = MessagePack::Factory.new

Slide 93

Slide 93 text

factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ... ) Extension Type

Slide 94

Slide 94 text

factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ... ) type

Slide 95

Slide 95 text

factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ... ) class (matches subclasses!)

Slide 96

Slide 96 text

factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ... ) serializer/ deserializer

Slide 97

Slide 97 text

packer: ->(date) { }, unpacker: ->(str) { }

Slide 98

Slide 98 text

packer: ->(date) { [date.year, date.month, date.day].pack("s< C C") }, unpacker: ->(str) { } Array#pack

Slide 99

Slide 99 text

packer: ->(date) { [date.year, date.month, date.day].pack("s< C C") }, unpacker: ->(str) { year, month, date = str.unpack("s< C C") Date.new(year, month, day) } String#unpack

Slide 100

Slide 100 text

packer: ->(date) { [date.year, date.month, date.day].pack("s< C C") }, unpacker: ->(str) { year, month, date = str.unpack("s< C C") Date.new(year, month, day) }

Slide 101

Slide 101 text

date = Date.new(2022, 5, 17) #=> Tue, 17 May 2022

Slide 102

Slide 102 text

date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) #=> "\xD6\x03\xE6\a\x05\x11"

Slide 103

Slide 103 text

date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) #=> "\xD6\x03\xE6\a\x05\x11" d603 e607 0511 type 3 2022 05 17

Slide 104

Slide 104 text

date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) factory.load(encoded_date) #=> Tue, 17 May 2022

Slide 105

Slide 105 text

date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) factory.load(encoded_date) factory.dump({ "foo" => [Object.new] })

Slide 106

Slide 106 text

date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) factory.load(encoded_date) factory.dump({ "foo" => [Object.new] }) NoMethodError: undefined method `to_msgpack' for <#Object:0x...>

Slide 107

Slide 107 text

Marshal MessagePack

Slide 108

Slide 108 text

factory.dump

Slide 109

Slide 109 text

MSGPACK XX factory.dump Version Byte Prefix

Slide 110

Slide 110 text

MSGPACK XX rescue NoMethodError factory.dump

Slide 111

Slide 111 text

MSGPACK XX rescue NoMethodError Marshal.dump MARSHAL 0408 factory.dump

Slide 112

Slide 112 text

...

Slide 113

Slide 113 text

...

Slide 114

Slide 114 text

No content

Slide 115

Slide 115 text

Symbol Time DateTime Date BigDecimal

Slide 116

Slide 116 text

Symbol Time DateTime Date BigDecimal 00

Slide 117

Slide 117 text

Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01

Slide 118

Slide 118 text

Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 attributes cached associations

Slide 119

Slide 119 text

factory.register_type( 0x06, ActiveRecord::Base, packer: ->(value) { ActiveRecordPacker.dump(value) }, unpacker: ->(value) { ActiveRecordPacker.load(value) } )

Slide 120

Slide 120 text

factory.register_type( 0x06, ActiveRecord::Base, packer: ->(value) { ActiveRecordPacker.dump(value) }, unpacker: ->(value) { ActiveRecordPacker.load(value) } )

Slide 121

Slide 121 text

ActiveRecordPacker.dump(value) ActiveRecordCoder.dump(value)

Slide 122

Slide 122 text

class Post has_many :comments end class Comment belongs_to :post, inverse_of: :comments end

Slide 123

Slide 123 text

Post Comment Post Comment Post Comment Comment Instance Tracker 0 <#Post> 1 <#Comment> 2 <#Comment> :comments 0 1 :post 0 2 :post 0

Slide 124

Slide 124 text

Post Comment Post Comment Post Comment Comment Instance Tracker 0 <#Post> 1 <#Comment> 2 <#Comment> :comments 0 1 :post 0 2 :post 0

Slide 125

Slide 125 text

Post Comment Post Comment Post Comment Comment Instance Tracker [0, [ [:comments, [[1, [:post, 0]], [2, [:post, 0]]]]]] 0 <#Post> 1 <#Comment> 2 <#Comment>

Slide 126

Slide 126 text

Post Comment Post Comment Post Comment Comment Instance Tracker [0, [ [:comments, [[1, [:post, 0]], [2, [:post, 0]]]]]] 0 <#Post> 1 <#Comment> 2 <#Comment> [["Post", {"id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>2, ...}]]

Slide 127

Slide 127 text

[ [0, [ [:comments, [[1, [:post, 0]], [2, [:post, 0]]]]]], [["Post", {"id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>2, ...}]] ] associations records

Slide 128

Slide 128 text

c801 2b06 9492 0091 92d7 0063 6f6d 6d65 6e74 7392 9201 9192 d600 706f 7374 0092 0291 92d6 0070 6f73 7400 92a4 506f 7374 84a2 6964 01a5 7469 746c 65b7 4361 6368 696e 6720 5769 7468 6f75 7420 4d61 7273 6861 6caa 6372 6561 7465 645f 6174 c70f 08f8 cd68 6200 0000 0058 cccd 0d55 5443 aa75 7064 6174 6564 5f61 74c7 0f08 f8cd 6862 0000 0000 58cc cd0d 5554 4392 a743 6f6d 6d65 6e74 84a7 706f 7374 5f69 6401 a269 6401 aa63 7265 6174 6564 5f61 74c7 0f08 2a79 7862 0000 0000 08b8 4630 5554 43aa 7570 6461 7465 645f 6174 c70f 082a 7978 6200 0000 0008 b846 3055 5443 92a7 436f 6d6d 656e 7484 a269 6402 aa63 7265 6174 6564 5f61 74c7 0f08 7979 7862 0000 0000 b0c2 7c1f 5554 43aa 7570 6461 7465 645f 6174 c70f 0879 7978 6200 0000 00b0 c27c 1f55 5443 a770 6f73 745f 6964 01 ActiveRecordCoder + MessagePack (303 bytes)

Slide 129

Slide 129 text

c801 2b06 9492 0091 92d7 0063 6f6d 6d65 6e74 7392 9201 9192 d600 706f 7374 0092 0291 92d6 0070 6f73 7400 92a4 506f 7374 84a2 6964 01a5 7469 746c 65b7 4361 6368 696e 6720 5769 7468 6f75 7420 4d61 7273 6861 6caa 6372 6561 7465 645f 6174 c70f 08f8 cd68 6200 0000 0058 cccd 0d55 5443 aa75 7064 6174 6564 5f61 74c7 0f08 f8cd 6862 0000 0000 58cc cd0d 5554 4392 a743 6f6d 6d65 6e74 84a7 706f 7374 5f69 6401 a269 6401 aa63 7265 6174 6564 5f61 74c7 0f08 2a79 7862 0000 0000 08b8 4630 5554 43aa 7570 6461 7465 645f 6174 c70f 082a 7978 6200 0000 0008 b846 3055 5443 92a7 436f 6d6d 656e 7484 a269 6402 aa63 7265 6174 6564 5f61 74c7 0f08 7979 7862 0000 0000 b0c2 7c1f 5554 43aa 7570 6461 7465 645f 6174 c70f 0879 7978 6200 0000 00b0 c27c 1f55 5443 a770 6f73 745f 6964 01 0408 6f3a 0950 6f73 7411 3a10 406e 6577 5f72 6563 6f72 6446 3a10 4061 7474 7269 6275 7465 736f 3a22 4163 7469 7665 4d6f 6465 6c3a 3a4c 617a 7941 7474 7269 6275 7465 5365 740c 3b07 7b09 4922 0769 6406 3a06 4554 6f3a 2941 6374 6976 654d 6f64 656c 3a3a 4174 7472 6962 7574 653a 3a46 726f 6d44 6174 6162 6173 650a 3a0a 406e 616d 6540 083a 1c40 7661 6c75 655f 6265 666f 7265 5f74 7970 655f 6361 7374 6906 3a0a 4074 7970 656f 3a45 4163 7469 7665 5265 636f 7264 3a3a 436f 6e6e 6563 7469 6f6e 4164 6170 7465 7273 3a3a 5351 4c69 7465 3341 6461 7074 6572 3a3a 5351 4c69 7465 3349 6e74 6567 6572 093a 0f40 7072 6563 6973 696f 6e30 3a0b 4073 6361 6c65 303a 0b40 6c69 6d69 7430 3a0b 4072 616e 6765 6f3a 0a52 616e 6765 083a 0965 7863 6c54 3a0a 6265 6769 6e6c 2d09 0000 0000 0000 0080 3a08 656e 646c 2b09 0000 0000 0000 0080 3a18 406f 7269 6769 6e61 6c5f 6174 7472 6962 7574 6530 3a0b 4076 616c 7565 6906 4922 0a74 6974 6c65 063b 0954 6f3b 0a0a 3b0b 400e 3b0c 4922 1c43 6163 6869 6e67 2057 6974 686f 7574 204d 6172 7368 616c 063b 0954 3b0d 6f3a 1e41 6374 6976 654d 6f64 656c 3a3a 5479 7065 3a3a 5374 7269 6e67 0a3a 0a40 7472 7565 4922 0674 063b 0954 3a0b 4066 616c 7365 4922 0666 063b 0954 3b0f 303b 1030 3b11 303b 1730 3b18 4922 1c43 6163 6869 6e67 2057 6974 686f 7574 204d 6172 7368 616c 063b 0954 4922 0f63 7265 6174 6564 5f61 7406 3b09 546f 3b0a 0a3b 0b40 153b 0c49 221f 3230 3232 2d30 342d 3237 2030 353a 3030 3a34 302e 3233 3135 3931 063b 0954 3b0d 553a 4a41 6374 6976 6552 6563 6f72 643a 3a41 7474 7269 6275 7465 4d65 7468 6f64 733a 3a54 696d 655a 6f6e 6543 6f6e 7665 7273 696f 6e3a 3a54 696d 655a 6f6e 6543 6f6e 7665 7274 6572 5b09 3a0b 5f5f 7632 5f5f 5b00 5b00 6f3a 2141 6374 6976 6552 6563 6f72 643a 3a54 7970 653a 3a44 6174 6554 696d 6508 3b0f 690b 3b10 303b 1130 3b17 303b 1855 3a20 4163 7469 7665 5375 7070 6f72 743a 3a54 696d 6557 6974 685a 6f6e 655b 0849 753a 0954 696d 650d 658f 1ec0 a788 8302 063a 097a 6f6e 6549 2208 5554 4306 3b09 4649 2208 5554 4306 3b09 5449 753b 200d 658f 1ec0 a788 8302 063b 2140 1f49 220f 7570 6461 7465 645f 6174 063b 0954 6f3b 0a0a 3b0b 4023 3b0c 4922 1f32 3032 322d 3034 2d32 3720 3035 3a30 303a 3430 2e32 3331 3539 3106 3b09 543b 0d55 3b1c 5b09 3b1d 5b00 5b00 401c 3b17 303b 1855 3b1f 5b08 4975 3b20 0d65 8f1e c0a7 8883 0206 3b21 401f 4021 4975 3b20 0d65 8f1e c0a7 8883 0206 3b21 401f 3a0c 4076 616c 7565 737b 0940 0869 0640 0e40 1040 1540 1740 2340 253a 0b40 7479 7065 737d 0940 0840 0a40 0e40 1140 1540 1840 2340 266f 3a1d 4163 7469 7665 4d6f 6465 6c3a 3a54 7970 653a 3a56 616c 7565 083b 0f30 3b10 303b 1130 3a16 4061 6464 6974 696f 6e61 6c5f 7479 7065 737b 003a 1840 6465 6661 756c 745f 6174 7472 6962 7574 6573 7b06 4008 6f3b 0a09 3b0b 4008 3b0c 303b 0d40 0a3b 1730 3a13 4063 6173 7465 645f 7661 6c75 6573 7b00 3a12 406d 6174 6572 6961 6c69 7a65 6454 3a17 4061 7373 6f63 6961 7469 6f6e 5f63 6163 6865 7b06 3a0d 636f 6d6d 656e 7473 553a 3341 6374 6976 6552 6563 6f72 643a 3a41 7373 6f63 6961 7469 6f6e 733a 3a48 6173 4d61 6e79 4173 736f 6369 6174 696f 6e5b 073b 2a5b 0f5b 073a 0b40 6f77 6e65 7240 005b 073a 1340 6469 7361 626c 655f 6a6f 696e 7346 5b07 3a0c 406c 6f61 6465 6454 5b07 3a0c 4074 6172 6765 745b 076f 3a0c 436f 6d6d 656e 7411 3b06 463b 076f 3b08 0c3b 077b 0949 220c 706f 7374 5f69 6406 3b09 466f 3b0a 0a3b 0b40 413b 0c69 063b 0d40 0a3b 1730 3b18 6906 4008 6f3b 0a0a 3b0b 4008 3b0c 6906 3b0d 400a 3b17 303b 1869 0640 156f 3b0a 0a3b 0b40 153b 0c49 221f 3230 3232 2d30 352d 3039 2030 323a 3135 3a30 362e 3830 3939 3431 063b 0954 3b0d 553b 1c5b 093b 1d5b 005b 0040 1c3b 1730 3b18 553b 1f5b 0849 753b 200d 2291 1ec0 d55b 6c3c 063b 2140 1f40 2149 753b 200d 2291 1ec0 d55b 6c3c 063b 2140 1f40 236f 3b0a 0a3b 0b40 233b 0c49 221f 3230 3232 2d30 352d 3039 2030 323a 3135 3a30 362e 3830 3939 3431 063b 0954 3b0d 553b 1c5b 093b 1d5b 005b 0040 1c3b 1730 3b18 553b 1f5b 0849 753b 200d 2291 1ec0 d55b 6c3c 063b 2140 1f40 2149 753b 200d 2291 1ec0 d55b 6c3c 063b 2140 1f3b 227b 0940 0869 0640 1540 4540 2340 4f49 220c 706f 7374 5f69 6406 3b09 5469 063b 237d 0940 0840 0a40 1540 4640 2340 5040 5940 0a40 303b 257b 003b 267b 0640 086f 3b0a 093b 0b40 083b 0c30 3b0d 400a 3b17 303b 277b 003b 2854 3b29 7b06 3a09 706f 7374 553a 3541 6374 6976 6552 6563 6f72 643a 3a41 7373 6f63 6961 7469 6f6e 733a 3a42 656c 6f6e 6773 546f 4173 736f 6369 6174 696f 6e5b 073b 315b 0c5b 073b 2c40 3e5b 073b 2d46 5b07 3b2e 545b 073b 2f40 005b 073a 1140 7374 616c 655f 7374 6174 6549 2206 3106 3b09 465b 073a 0d40 7570 6461 7465 6446 5b07 3a17 4061 7373 6f63 6961 7469 6f6e 5f73 636f 7065 303a 0e40 7265 6164 6f6e 6c79 463a 1b40 7072 6576 696f 7573 6c79 5f6e 6577 5f72 6563 6f72 6446 3a0f 4064 6573 7472 6f79 6564 463a 1c40 6d61 726b 6564 5f66 6f72 5f64 6573 7472 7563 7469 6f6e 463a 1e40 6465 7374 726f 7965 645f 6279 5f61 7373 6f63 6961 7469 6f6e 303a 1e40 5f73 7461 7274 5f74 7261 6e73 6163 7469 6f6e 5f73 7461 7465 303a 1140 7072 696d 6172 795f 6b65 7940 083a 1440 7374 7269 6374 5f6c 6f61 6469 6e67 463a 1940 7374 7269 6374 5f6c 6f61 6469 6e67 5f6d 6f64 653a 0861 6c6c 6f3b 301b 3b06 463b 076f 3a1e 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 5365 7406 3b07 7b09 4008 6f3b 0a0a 3b0b 4008 3b0c 6907 3b0d 400a 3b17 303b 1869 0740 156f 3b0a 0a3b 0b40 153b 0c55 3b1f 5b08 4975 3b20 0d22 911e c08e 0f98 4106 3b21 401f 4021 4975 3b20 0d22 911e c08e 0f98 4106 3b21 401f 3b0d 4046 3b17 303b 1840 7040 236f 3b0a 0a3b 0b40 233b 0c55 3b1f 5b08 4072 4021 4975 3b20 0d22 911e c08e 0f98 4106 3b21 401f 3b0d 4050 3b17 303b 1840 7540 596f 3b0a 0a3b 0b40 593b 0c69 063b 0d40 0a3b 1730 3b18 6906 3b29 7b06 3b31 553b 325b 073b 315b 0c5b 073b 2c40 6b5b 073b 2d46 5b07 3b2e 545b 073b 2f40 005b 073b 3349 2206 3106 3b09 465b 073b 3446 5b07 3b35 303b 3646 3b37 543b 3846 3b39 463b 3a30 3b3b 303b 3c40 083b 3d46 3b3e 3b3f 3a1d 406d 7574 6174 696f 6e73 5f66 726f 6d5f 6461 7461 6261 7365 303a 2440 5f6e 6577 5f72 6563 6f72 645f 6265 666f 7265 5f6c 6173 745f 636f 6d6d 6974 543a 1840 7661 6c69 6461 7469 6f6e 5f63 6f6e 7465 7874 303a 0c40 6572 726f 7273 6f3a 1841 6374 6976 654d 6f64 656c 3a3a 4572 726f 7273 073a 0a40 6261 7365 406b 3b44 5b00 3a13 405f 746f 7563 685f 7265 636f 7264 543a 1540 5f61 6c72 6561 6479 5f63 616c 6c65 647b 063a 2961 7574 6f73 6176 655f 6173 736f 6369 6174 6564 5f72 6563 6f72 6473 5f66 6f72 5f70 6f73 7446 3a20 406d 7574 6174 696f 6e73 5f62 6566 6f72 655f 6c61 7374 5f73 6176 656f 3a2a 4163 7469 7665 4d6f 6465 6c3a 3a41 7474 7269 6275 7465 4d75 7461 7469 6f6e 5472 6163 6b65 7207 3b07 6f3b 4006 3b07 7b09 4008 6f3a 2541 6374 6976 654d 6f64 656c 3a3a 4174 7472 6962 7574 653a 3a46 726f 6d55 7365 720a 3b0b 4008 3b0c 6907 3b0d 400a 3b17 6f3b 0a0a 3b0b 4008 3b0c 303b 0d40 0a3b 1730 3b18 303b 1869 0740 156f 3b4c 0a3b 0b40 153b 0c40 723b 0d40 463b 176f 3b0a 0a3b 0b40 153b 0c30 3b0d 4046 3b17 303b 1830 3b18 4070 4023 6f3b 4c0a 3b0b 4023 3b0c 4072 3b0d 4050 3b17 6f3b 0a0a 3b0b 4023 3b0c 303b 0d40 503b 1730 3b18 303b 1840 7540 596f 3b4c 0a3b 0b40 593b 0c69 063b 0d40 0a3b 176f 3b0a 093b 0b40 593b 0c30 3b0d 400a 3b17 303b 1869 063a 1440 666f 7263 6564 5f63 6861 6e67 6573 7b00 3a1f 405f 636f 6d6d 6974 7465 645f 616c 7265 6164 795f 6361 6c6c 6564 463a 1f40 5f74 7269 6767 6572 5f64 6573 7472 6f79 5f63 616c 6c62 6163 6b46 3a1e 405f 7472 6967 6765 725f 7570 6461 7465 5f63 616c 6c62 6163 6b46 5b07 3b33 305b 073a 1f40 7265 706c 6163 6564 5f6f 725f 6164 6465 645f 7461 7267 6574 736f 3a08 5365 7406 3a0a 4068 6173 687d 0046 5b07 3a15 4061 7373 6f63 6961 7469 6f6e 5f69 6473 305b 073b 356f 3a23 436f 6d6d 656e 743a 3a41 6374 6976 6552 6563 6f72 645f 5265 6c61 7469 6f6e 0d3a 0b40 6b6c 6173 7363 0c43 6f6d 6d65 6e74 3a0b 4074 6162 6c65 6f3a 1041 7265 6c3a 3a54 6162 6c65 093b 0b49 220d 636f 6d6d 656e 7473 063b 0954 3b56 4001 963a 1140 7479 7065 5f63 6173 7465 726f 3a22 4163 7469 7665 5265 636f 7264 3a3a 5479 7065 4361 7374 6572 3a3a 4d61 7006 3b56 4001 963a 1140 7461 626c 655f 616c 6961 7330 3b22 7b07 3a0e 6578 7465 6e64 696e 675b 003a 0a77 6865 7265 6f3a 2841 6374 6976 6552 6563 6f72 643a 3a52 656c 6174 696f 6e3a 3a57 6865 7265 436c 6175 7365 063a 1040 7072 6564 6963 6174 6573 5b06 6f3a 1a41 7265 6c3a 3a4e 6f64 6573 3a3a 4571 7561 6c69 7479 073a 0a40 6c65 6674 533a 2041 7265 6c3a 3a41 7474 7269 6275 7465 733a 3a41 7474 7269 6275 7465 073a 0d72 656c 6174 696f 6e40 0197 3a09 6e61 6d65 4041 3a0b 4072 6967 6874 6f3a 2b41 6374 6976 6552 6563 6f72 643a 3a52 656c 6174 696f 6e3a 3a51 7565 7279 4174 7472 6962 7574 6509 3b0b 4041 3b0c 6906 3b0d 400a 3b17 303b 2e46 3a17 4070 7265 6469 6361 7465 5f62 7569 6c64 6572 6f3a 2341 6374 6976 6552 6563 6f72 643a 3a50 7265 6469 6361 7465 4275 696c 6465 7207 3b57 6f3a 2041 6374 6976 6552 6563 6f72 643a 3a54 6162 6c65 4d65 7461 6461 7461 083b 5640 0196 3a10 4061 7265 6c5f 7461 626c 6540 0197 3a10 4072 6566 6c65 6374 696f 6e30 3a0e 4068 616e 646c 6572 735b 0a5b 0763 0853 6574 6f3a 3141 6374 6976 6552 6563 6f72 643a 3a50 7265 6469 6361 7465 4275 696c 6465 723a 3a41 7272 6179 4861 6e64 6c65 7206 3b67 4001 a15b 0763 0a41 7272 6179 6f3b 6d06 3b67 4001 a15b 0763 1b41 6374 6976 6552 6563 6f72 643a 3a52 656c 6174 696f 6e6f 3a34 4163 7469 7665 5265 636f 7264 3a3a 5072 6564 6963 6174 6542 7569 6c64 6572 3a3a 5265 6c61 7469 6f6e 4861 6e64 6c65 7200 5b07 630a 5261 6e67 656f 3a31 4163 7469 7665 5265 636f 7264 3a3a 5072 6564 6963 6174 6542 7569 6c64 6572 3a3a 5261 6e67 6548 616e 646c 6572 063b 6740 01a1 5b07 6310 4261 7369 634f 626a 6563 746f 3a37 4163 7469 7665 5265 636f 7264 3a3a 5072 6564 6963 6174 6542 7569 6c64 6572 3a3a 4261 7369 634f 626a 6563 7448 616e 646c 6572 063b 6740 01a1 3a17 4064 656c 6567 6174 655f 746f 5f6b 6c61 7373 463a 1340 6675 7475 7265 5f72 6573 756c 7430 3a0d 4072 6563 6f72 6473 305b 073a 0b40 7072 6f78 796f 3a37 436f 6d6d 656e 743a 3a41 6374 6976 6552 6563 6f72 645f 4173 736f 6369 6174 696f 6e73 5f43 6f6c 6c65 6374 696f 6e50 726f 7879 113a 1140 6173 736f 6369 6174 696f 6e40 363b 5640 0196 3b57 4001 973b 227b 003b 2e46 3b67 4001 a13b 7146 3b72 303b 7330 3a0a 4074 616b 6530 3a0d 406f 6666 7365 7473 303a 0b40 7363 6f70 6530 5b07 3a11 405f 7761 735f 6c6f 6164 6564 303b 3646 3b37 463b 3846 3b39 463b 3a30 3b3b 303b 3c40 083b 3d46 3b3e 3b3f Marshal (4014 bytes)

Slide 130

Slide 130 text

Rails cache memcached fill percent

Slide 131

Slide 131 text

No content

Slide 132

Slide 132 text

[ [0, [ [:comments, [[1, [:post, 0]], [2, [:post, 0]]]]]], [["Post", {"id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>1, ...}], ["Comment", {"post_id"=>1, "id"=>2, ...}]] ] associations records hard-coded!

Slide 133

Slide 133 text

CACHE_MISS_ERRORS = [ Paquito::ActiveRecordCoder::Error, Paquito::ClassMissingError, Paquito::VersionMismatchError, Paquito::UnpackError, Paquito::UnsupportedCodec, ] def handle_exceptions(...) super rescue *CACHE_MISS_ERRORS on_miss end just pretend it wasn’t there

Slide 134

Slide 134 text

Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 HashWithIndifferentAccess

Slide 135

Slide 135 text

Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 03 HashWithIndifferentAccess ActiveSupport::TimeWithZone

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 03 7f Object HashWithIndifferentAccess ActiveSupport::TimeWithZone 04 ...

Slide 138

Slide 138 text

class Task def initialize(title, content) @title, @content = title, content end def as_pack [@title, @content] end def self.from_pack(payload) title, content = payload new(title, content) end end “packable”

Slide 139

Slide 139 text

MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct)

Slide 140

Slide 140 text

MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct) my_struct = MyStruct.new("foo", "bar") my_struct.as_pack #=> [26450, "foo", "bar"] digest

Slide 141

Slide 141 text

MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct) my_struct = MyStruct.new("foo", "bar") my_struct.as_pack #=> [26450, "foo", "bar"] MyStruct.from_pack([26450, "foo", "bar"]) #=> #

Slide 142

Slide 142 text

MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct) my_struct = MyStruct.new("foo", "bar") my_struct.as_pack #=> [26450, "foo", "bar"] MyStruct.from_pack([26450, "foo", "bar"]) #=> # MyStruct.from_pack([123, "foo", "bar"]) # MyStruct digests do not match!

Slide 143

Slide 143 text

No content

Slide 144

Slide 144 text

MessagePack

Slide 145

Slide 145 text

Shopify/paquito

Slide 146

Slide 146 text

Shopify/paquito Jean Boussier (@byroot)

Slide 147

Slide 147 text

Chris Salzberg @shioyama Thanks!