Class: Rails::GraphQL::Subscription::Store::Memory
- Defined in:
- lib/rails/graphql/subscription/store/memory.rb
Overview
GraphQL Memory Subscription Store
This store will save all the subscriptions in a very similar way that the TypeMap works, using nested concurrent maps that points out to them. Everything is based on the sid of the subscription
Instance Attribute Summary collapse
-
#index ⇒ Object
readonly
Returns the value of attribute index.
-
#list ⇒ Object
readonly
Returns the value of attribute list.
Instance Method Summary collapse
- #add(subscription) ⇒ Object
- #all ⇒ Object
- #fetch(*sids) ⇒ Object
- #has?(item) ⇒ Boolean
-
#initialize ⇒ Memory
constructor
A new instance of Memory.
- #remove(item) ⇒ Object
- #search(**xargs, &block) ⇒ Object (also: #find_each)
- #serialize(**xargs) ⇒ Object
- #update!(item) ⇒ Object
Methods inherited from Base
Constructor Details
#initialize ⇒ Memory
Returns a new instance of Memory.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 15 def initialize # The list store a simple association between sid and @list = Concurrent::Map.new # This store the index in a way that is possible to search # subscriptions in a fast manner @index = Concurrent::Map.new do |h1, key1| # Fields scopes = Concurrent::Map.new do |h2, key2| # Scopes arguments = Concurrent::Map.new do |h3, key3| # Arguments h3.fetch_or_store(key3, Concurrent::Array.new) # SIDs end h2.fetch_or_store(key2, arguments) end h1.fetch_or_store(key1, scopes) end end |
Instance Attribute Details
#index ⇒ Object (readonly)
Returns the value of attribute index.
13 14 15 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 13 def index @index end |
#list ⇒ Object (readonly)
Returns the value of attribute list.
13 14 15 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 13 def list @list end |
Instance Method Details
#add(subscription) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 47 def add(subscription) if has?(subscription.sid) raise ::ArgumentError, +"SID #{subscription.sid} is already taken." end # Rewrite the scope, to save memory scope = possible_scopes(subscription.scope)&.first subscription.instance_variable_set(:@scope, scope) # Save to the list and to the index list[subscription.sid] = subscription index_set = subscription_to_index(subscription).reduce(index, &:[]) index_set << subscription.sid subscription.sid end |
#all ⇒ Object
43 44 45 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 43 def all list.keys end |
#fetch(*sids) ⇒ Object
63 64 65 66 67 68 69 70 71 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 63 def fetch(*sids) return if sids.none? items = sids.map do |item| instance?(item) ? item : list[item] end items.one? ? items.first : items end |
#has?(item) ⇒ Boolean
94 95 96 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 94 def has?(item) list.key?(instance?(item) ? item.sid : item) end |
#remove(item) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 73 def remove(item) return unless has?(item) instance = instance?(item) ? item : fetch(item) path = subscription_to_index(instance) index.delete(instance.sid) f_level = index[path[0]] s_level = f_level[path[1]] a_level = s_level[path[2]] a_level.delete(instance.sid) s_level.delete(path[2]) if a_level.empty? f_level.delete(path[1]) if s_level.empty? index.delete(path[0]) if f_level.empty? end |
#search(**xargs, &block) ⇒ Object Also known as: find_each
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 98 def search(**xargs, &block) xargs = serialize(**xargs) field, scope, args = xargs.values_at(:field, :scope, :args) if field.nil? && args.nil? && scope.nil? list.each(&block) unless block.nil? return all end [].tap do |result| GraphQL.enumerate(field || index.keys).each do |key1| GraphQL.enumerate(scope || index[key1].keys).each do |key2| GraphQL.enumerate(args || index[key2].keys).each do |key3| items = index.fetch(key1, nil)&.fetch(key2, nil)&.fetch(key3, nil) items.each(&list.method(:[])).each(&block) unless block.nil? result.concat(items || EMPTY_ARRAY) end end end end end |
#serialize(**xargs) ⇒ Object
34 35 36 37 38 39 40 41 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 34 def serialize(**xargs) return xargs if !xargs.key?(:field) || xargs[:field].is_a?(Numeric) xargs[:field] = hash_for(xargs[:field]) xargs[:scope] = possible_scopes(xargs[:scope]) xargs[:args] = Array.wrap(xargs[:args]).map(&method(:hash_for)) xargs end |
#update!(item) ⇒ Object
90 91 92 |
# File 'lib/rails/graphql/subscription/store/memory.rb', line 90 def update!(item) (instance?(item) ? item : fetch(item)).update! end |