Ohm

7,927 views

Published on

Interacting directly with a datastore can have many pitfalls. The presentation goes through an example which exposes some of the pitfalls, then shows how Ohm helps to solve them or make them a non issue. Some basic features of Ohm also covered.

Published in: Technology, Spiritual
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
7,927
On SlideShare
0
From Embeds
0
Number of Embeds
631
Actions
Shares
0
Downloads
33
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • We’re going to build up to why we need Ohm with an example of the pitfalls of trying to roll your own solution to interact with redis as a datastore.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Get reference to database\n
  • \n
  • \n
  • Awesome - we’re storing our information in redis!\nSo what’s wrong with this approach?\n
  • \n
  • The key we’re using for symbols isn’t adequate for multiple symbols...\n
  • The key we’re using for symbols isn’t adequate for multiple symbols...\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Using a set because each element will be unique\nOrder isn’t important\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • index: creates an index for an attribute you want to be able to search\ncollection: similar to has_many\n
  • \n
  • Validation behaves similarly to what we see in AR\nErrors are returned as an array of attributes and the associated failure\n
  • Error messages are not defined within the model, but with a presenter\n\nerror_messages is just an array of errors\n
  • Notice that the phoneme is added to the symbols phonemes\nAND a phoneme gets a reference to ancient_symbol\n
  • \n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • attribute->string set->unordered array list->array (great for queue) reference->foreign key collection->has_many\n
  • \n
  • Ohm contrib is a collection of drop-in modules\n
  • \n
  • \n
  • \n
  • Ohm

    1. OhmObject hash map Christopher Spring
    2. A littlebackgroundinfo first...
    3. Ohm runs on redis
    4. Ohm runs on redisRemote dictionary server
    5. Ohm runs on redisRemote dictionary serverStore multiple data-structure types
    6. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes
    7. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategies
    8. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scale
    9. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactions
    10. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactionsKey expiry
    11. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactionsKey expiryredis-rb
    12. What is Ohm?
    13. Ancient syllable
    14. Ancient syllableAaa-ooo-mmm
    15. Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universe
    16. Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universeBrahma, Vishnu & Shiva
    17. or...
    18. symbol = { :name => Ohm, :description => Ancient syllable, :phonemes => [ { :sound => aaa, :meaning => beginning of the universe, :god => Brahma }, { :sound => ooo, :meaning => duration of the universe, :god => Vishnu }, { :sound => mmm, :meaning => dissolution of the universe, :god => Shiva } ]}
    19. Let’s store that inredis...
    20. require redisdb = Redis.new
    21. # make a bunch of phonemes# HMSET key field value [field value ...]phos = %w(pho1 pho2 pho3)db.hmset phos[1], sound, aaa, meaning, beginning, god, Brahmadb.hmset phos[2], sound, ooo, meaning, duration, god, Vishnudb.hmset phos[3], sound, mmm, meaning, dissolution, god, Shiva
    22. # ... and create the symboldb.hmset symbol, name, Ohm description, Ancient syllable, phonemes, phos.to_json
    23. require redisdb = Redis.newphos = %w(pho1 pho2 pho3)db.hmset phos[1], sound, aaa, meaning, beginning,god, Brahmadb.hmset phos[2], sound, ooo, meaning, duration,god, Vishnudb.hmset phos[3], sound, mmm, meaning, dissolution,god, Shivadb.hmset symbol, name, Ohm description, Ancient syllable, alternatives, alternatives, phenomes, phos.to_json
    24. Awesome?
    25. I want lot’s of Symbols
    26. I want lot’s of Symbols db.hmset symbol, name, Ohm description, Ancient syllable, alternatives, alternatives, phenomes, phos.to_json
    27. I want lot’s of Symbols
    28. I want lot’s of Symbols
    29. I want lot’s of Symbols Require a key strategy
    30. I want lot’s of Symbols Require a key strategy Store the key in redis
    31. I want lot’s of Symbols Require a key strategy Store the key in redis Auto-increment
    32. # "symbol:1", "symbol:2" ... "symbol:n"def get_symbol_pk pk = db.incr symbol:pk "symbol:#{pk}"end# ...db.hmset get_symbol_pk, ...
    33. Ok, but...
    34. I wanna find symbols byname!
    35. I wanna find symbols byname!Requires an extra index
    36. I wanna find symbols byname!Requires an extra indexStore index in a hash or a set
    37. I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy
    38. I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy...
    39. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}"end# Transaction...db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, name, symbol_name, ... store_name_index symbol_key, symbol_nameend
    40. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}"end# Transaction...db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, name, symbol_name, ... store_name_index symbol_key, symbol_nameend
    41. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}"end# Transaction...db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, name, symbol_name, ... store_name_index symbol_key, symbol_nameend
    42. Fine, but now i want...
    43. Fine, but now i want... Validation
    44. Fine, but now i want... Validation To use this in project X
    45. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme
    46. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme ... shoot me?
    47. This sucks!! Not OO at all Validation? Referencing containing object What other pitfalls have we missed? Project/implementation specific ...
    48. Let’s build our own objectmapping on top of redis!
    49. or...
    50. Ohm: Object hash map
    51. symbol = { :name => Ohm, :description => Ancient syllable, :phonemes => [ { :sound => aaa, :meaning => beginning of the universe, :god => Brahma }, { :sound => ooo, :meaning => duration of the universe, :god => Vishnu }, { :sound => mmm, :meaning => dissolution of the universe, :god => Shiva } ]}
    52. require rubygemsrequire ohmclass AncientSymbol < Ohm::Model attribute :name attribute :description index :name collection :phonemes, Phoneme def validate assert_present :name endend
    53. class Phoneme < Ohm::Model attribute :sound attribute :meaning attribute :god index :sound index :god reference :ancient_symbol, AncientSymbol def validate assert_present :sound endend
    54. Ohm.connectsymbol = AncientSymbol.createp symbol.valid? # falsep symbol.errors # [[:name, :not_present]]
    55. error_messages = symbol.errors.present do |e| e.on [:name, :not_present] do "Symbols must have a name." endend
    56. symbol = AncientSymbol.new :name => Ohmif symbol.save symbol.phonemes << Phoneme.create( :sound => aaa, :meaning => beginnging of universe, :god => Brahma, :ancient_symbol => symbol ) # ...end
    57. Cool, so how do find stuff?
    58. Phoneme.all
    59. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>
    60. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo
    61. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>
    62. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa
    63. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>
    64. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]
    65. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
    66. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">
    67. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">pho.ancient_symbol
    68. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">pho.ancient_symbol# <AncientSymbol:1 name="Ohm" description=nil>
    69. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">pho.ancient_symbol# <AncientSymbol:1 name="Ohm" description=nil>symbol.phonemes
    70. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>pho = Phoneme[1]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">pho.ancient_symbol# <AncientSymbol:1 name="Ohm" description=nil>symbol.phonemes# <Set (Phoneme): ["3", "1", "2"]>
    71. We also get sorting...
    72. symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]
    73. symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]symbol.phonemes.sort_by( :sound, :order => ALPHA DESC )# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
    74. symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]symbol.phonemes.sort_by( :sound, :order => ALPHA DESC )# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]symbol.phonemes.sort_by( :sound, :get => :god )# ["Shiva", "Brahma", "Vishnu"]
    75. What else can we do?
    76. Attribute types attribute set list counter reference collection
    77. Available validation assert_present assert_format assert_numeric assert_unique
    78. ohm-contribBoundariesCallbacksTimestampingToHashWebValidationsNumberValidationsExtraValidationsTypecastLocking
    79. Awesome?
    80. Questions?
    81. Linkswww.christopherspring.comhttp://ohm.keyvalue.org/http://www.redis.io/

    ×