Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Caching Without Marshal
Search
Chris Salzberg
June 01, 2022
Programming
1
1.7k
Caching Without Marshal
Slides from my RailsConf 2022 talk about replacing Marshal with MessagePack in the Rails cache.
Chris Salzberg
June 01, 2022
Tweet
Share
More Decks by Chris Salzberg
See All by Chris Salzberg
Multiverse Ruby
shioyama
2
4.5k
Caching With MessagePack
shioyama
0
110
The Elusive Attribute
shioyama
0
700
building_generic_software.pdf
shioyama
0
610
Metaprogramming for Generalists
shioyama
2
2k
The Ruby Module Builder Pattern (Tokyo Rubyist Meetup)
shioyama
1
110
A Brief Introduction to AttributeMethods
shioyama
0
140
The Ruby Module Builder Pattern
shioyama
3
18k
Translating with Mobility
shioyama
0
2.1k
Other Decks in Programming
See All in Programming
AWS IaCの注目アップデート 2024年10月版
konokenj
3
3.1k
僕がつくった48個のWebサービス達
yusukebe
18
17k
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Rails 2024
falcon8823
6
2.3k
2万ページのSSG運用における工夫と注意点 / Vue Fes Japan 2024
chinen
3
1.4k
『ドメイン駆動設計をはじめよう』のモデリングアプローチ
masuda220
PRO
8
450
JaSST 24 九州:ワークショップ(は除く)実践!マインドマップを活用したソフトウェアテスト+活用事例
satohiroyuki
0
270
外部システム連携先が10を超えるシステムでのアーキテクチャ設計・実装事例
kiwasaki
1
230
CSC509 Lecture 09
javiergs
PRO
0
120
破壊せよ!データ破壊駆動で考えるドメインモデリング / data-destroy-driven
minodriven
16
4.1k
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
9
1k
色々なIaCツールを実際に触って比較してみる
iriikeita
0
280
RailsのPull requestsのレビューの時に私が考えていること
yahonda
5
2.1k
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
51
4.9k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
Six Lessons from altMBA
skipperchong
26
3.5k
Building Your Own Lightsaber
phodgson
102
6.1k
Become a Pro
speakerdeck
PRO
24
5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Bash Introduction
62gerente
608
210k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
355
29k
A designer walks into a library…
pauljervisheath
202
24k
Ruby is Unlike a Banana
tanoku
96
11k
Transcript
CACHING MARSHAL Chris Salzberg Without Without
Chris Salzberg @shioyama Staff Dev @ Ruby & Rails Infra
Team: Core Stewardship
None
before After
before After cache
let’s talk about caching caching
None
None
I CAN CACHE ALL THE THINGS
Rails.cache.write(...)
# 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
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
None
None
irb(main):010:0> Marshal.method(:dump).source
irb(main):010:0> Marshal.method(:dump).source Could not locate source for dump! (MethodSource::SourceNotFoundError)
let’s talk about Marshal Marshal
class Post < ApplicationRecord end
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8...
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8... serialized_post =
Marshal.dump(post)
1607 bytes!!! post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8...
serialized_post = Marshal.dump(post) #=> "\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"
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8... serialized_post =
Marshal.dump(post) #=> "\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
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8... serialized_post =
Marshal.dump(post) #=> "\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
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8... serialized_post =
Marshal.dump(post) #=> "\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
post = Post.create(title: "Caching Without Marshal") #=> #<Post:0x00000001062bd0e8... serialized_post =
Marshal.dump(post) Marshal.load(serialized_post) #=> #<Post:0x000000010652db48 # id: 1, # title: "Caching Without Marshal", # created_at: Wed, 27 Apr 2022 05:00:40.231591000 UTC +00:00, # updated_at: Wed, 27 Apr 2022 05:00:40.231591000 UTC +00:00>
marshal encodes the universe the universe
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'
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'
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
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
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
Objects Objects
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
\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: ...
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: ...
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
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
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
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
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...
variables variables
mystring = "Caching Without Marshal"
mystring = "Caching Without Marshal" mystring.instance_variable_set(:@hidden, true) mystring.instance_variable_get(:@hidden) #=> true
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) #=> ???
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
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
links links
myarray = []
myarray = [] myarray << myarray #=> [[...]]
myarray = [] myarray << myarray #=> [[...]] decoded =
Marshal.load(Marshal.dump(myarray)) #=> ???
myarray = [] myarray << myarray #=> [[...]] decoded =
Marshal.load(Marshal.dump(myarray)) #=> [[...]]
myarray = [] myarray << myarray #=> [[...]] decoded =
Marshal.load(Marshal.dump(myarray)) #=> [[...]] decoded.first == decoded #=> true
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
0408 5b06 4000
0408 5b06 4000 [ length TYPE_ARRAY
0408 5b06 4000 [ length @ position TYPE_LINK
core type core type subclasses subclasses
class MyHash < Hash end
class MyHash < Hash end my_hash = MyHash.new #=> {}
class MyHash < Hash end my_hash = MyHash.new my_hash.class #=>
MyHash
class MyHash < Hash end my_hash = MyHash.new encoded =
Marshal.dump(my_hash) decoded = Marshal.load(encoded) #=> {}
class MyHash < Hash end my_hash = MyHash.new encoded =
Marshal.dump(my_hash) decoded = Marshal.load(encoded) decoded.class #=> MyHash
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
MARSHAL MARSHAL RAILS DEVELOPER RAILS DEVELOPER
let’s talk about what we did what we did
before After cache
before After
We need a format that does not encode the universe.
None
None
encoded = MessagePack.pack({"foo" => "bar"})
encoded = MessagePack.pack({"foo" => "bar"}) => "\x81\xA3foo\xA3bar"
encoded = MessagePack.pack({"foo" => "bar"}) => "\x81\xA3foo\xA3bar" decoded = MessagePack.unpack(encoded)
=> {"foo"=>"bar"}
Core Types
Core Types atomic
Core Types composite
Core Types No Object Type
Core Types No Object Type No ivar Type
0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo")
0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo") foo "
length 3
0408 4922 0866 6f6f 063a 0645 54 Marshal.dump("foo") :E TYPE_IVAR
length 1 T “This string’s encoding is UTF-8.”
a366 6f6f MessagePack.pack("foo")
a366 6f6f MessagePack.pack("foo") foo
a366 6f6f MessagePack.pack("foo") foo (String type encoding is UTF-8.)
a366 6f6f MessagePack.pack("foo") 10100011 string of length < 31 bytes
a366 6f6f MessagePack.pack("foo") 10100011 length 3
None
ActiveRecord::Base
Object?
We need a format that does not encode the universe.
whole ^
We need a format that does not encode the universe.
(but let’s us encode parts of it) whole ^
factory = MessagePack::Factory.new
factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ...
) Extension Type
factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ...
) type
factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ...
) class (matches subclasses!)
factory = MessagePack::Factory.new factory.register_type( 0x03, Date, packer: ..., unpacker: ...
) serializer/ deserializer
packer: ->(date) { }, unpacker: ->(str) { }
packer: ->(date) { [date.year, date.month, date.day].pack("s< C C") }, unpacker:
->(str) { } Array#pack
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
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) }
date = Date.new(2022, 5, 17) #=> Tue, 17 May 2022
date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) #=> "\xD6\x03\xE6\a\x05\x11"
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
date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) factory.load(encoded_date) #=>
Tue, 17 May 2022
date = Date.new(2022, 5, 17) encoded_date = factory.dump(date) factory.load(encoded_date) factory.dump({
"foo" => [Object.new] })
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...>
Marshal MessagePack
factory.dump
MSGPACK XX factory.dump Version Byte Prefix
MSGPACK XX rescue NoMethodError factory.dump
MSGPACK XX rescue NoMethodError Marshal.dump MARSHAL 0408 factory.dump
...
...
None
Symbol Time DateTime Date BigDecimal
Symbol Time DateTime Date BigDecimal 00
Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01
Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 attributes cached
associations
factory.register_type( 0x06, ActiveRecord::Base, packer: ->(value) { ActiveRecordPacker.dump(value) }, unpacker: ->(value)
{ ActiveRecordPacker.load(value) } )
factory.register_type( 0x06, ActiveRecord::Base, packer: ->(value) { ActiveRecordPacker.dump(value) }, unpacker: ->(value)
{ ActiveRecordPacker.load(value) } )
ActiveRecordPacker.dump(value) ActiveRecordCoder.dump(value)
class Post has_many :comments end class Comment belongs_to :post, inverse_of:
:comments end
Post Comment Post Comment Post Comment Comment Instance Tracker 0
<#Post> 1 <#Comment> 2 <#Comment> :comments 0 1 :post 0 2 :post 0
Post Comment Post Comment Post Comment Comment Instance Tracker 0
<#Post> 1 <#Comment> 2 <#Comment> :comments 0 1 :post 0 2 :post 0
Post Comment Post Comment Post Comment Comment Instance Tracker [0,
[ [:comments, [[1, [:post, 0]], [2, [:post, 0]]]]]] 0 <#Post> 1 <#Comment> 2 <#Comment>
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, ...}]]
[ [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
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)
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)
Rails cache memcached fill percent
None
[ [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!
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
Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 HashWithIndifferentAccess
Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 03
HashWithIndifferentAccess ActiveSupport::TimeWithZone
None
Symbol Time DateTime Date BigDecimal ActiveRecord::Base 00 01 02 03
7f Object HashWithIndifferentAccess ActiveSupport::TimeWithZone 04 ...
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”
MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct)
MyStruct = Struct.new(:foo, :bar) MyStruct.include(Paquito::Struct) my_struct = MyStruct.new("foo", "bar") my_struct.as_pack
#=> [26450, "foo", "bar"] digest
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"]) #=> #<struct MyStruct foo="foo", bar="bar">
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"]) #=> #<struct MyStruct foo="foo", bar="bar"> MyStruct.from_pack([123, "foo", "bar"]) # MyStruct digests do not match!
None
MessagePack
Shopify/paquito
Shopify/paquito Jean Boussier (@byroot)
Chris Salzberg @shioyama Thanks!