File: memory.rb

package info (click to toggle)
ruby-flipper 0.26.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,288 kB
  • sloc: ruby: 16,377; sh: 61; javascript: 24; makefile: 14
file content (122 lines) | stat: -rw-r--r-- 3,253 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
require 'concurrent/atomic/read_write_lock'

module Flipper
  module Adapters
    # Public: Adapter for storing everything in memory.
    # Useful for tests/specs.
    class Memory
      include ::Flipper::Adapter

      FeaturesKey = :features

      # Public: The name of the adapter.
      attr_reader :name

      # Public
      def initialize(source = nil)
        @source = Hash.new.update(source || {})
        @name = :memory
        @lock = Concurrent::ReadWriteLock.new
      end

      # Public: The set of known features.
      def features
        @lock.with_read_lock { @source.keys }.to_set
      end

      # Public: Adds a feature to the set of known features.
      def add(feature)
        @lock.with_write_lock { @source[feature.key] ||= default_config }
        true
      end

      # Public: Removes a feature from the set of known features and clears
      # all the values for the feature.
      def remove(feature)
        @lock.with_write_lock { @source.delete(feature.key) }
        true
      end

      # Public: Clears all the gate values for a feature.
      def clear(feature)
        @lock.with_write_lock { @source[feature.key] = default_config }
        true
      end

      # Public
      def get(feature)
        @lock.with_read_lock { @source[feature.key] } || default_config
      end

      def get_multi(features)
        @lock.with_read_lock do
          result = {}
          features.each do |feature|
            result[feature.key] = @source[feature.key] || default_config
          end
          result
        end
      end

      def get_all
        @lock.with_read_lock { @source.to_h }
      end

      # Public
      def enable(feature, gate, thing)
        @lock.with_write_lock do
          @source[feature.key] ||= default_config

          case gate.data_type
          when :boolean
            @source[feature.key] = default_config
            @source[feature.key][gate.key] = thing.value.to_s
          when :integer
            @source[feature.key][gate.key] = thing.value.to_s
          when :set
            @source[feature.key][gate.key] << thing.value.to_s
          else
            raise "#{gate} is not supported by this adapter yet"
          end

          true
        end
      end

      # Public
      def disable(feature, gate, thing)
        @lock.with_write_lock do
          @source[feature.key] ||= default_config

          case gate.data_type
          when :boolean
            @source[feature.key] = default_config
          when :integer
            @source[feature.key][gate.key] = thing.value.to_s
          when :set
            @source[feature.key][gate.key].delete thing.value.to_s
          else
            raise "#{gate} is not supported by this adapter yet"
          end

          true
        end
      end

      # Public
      def inspect
        attributes = [
          'name=:memory',
          "source=#{@source.inspect}",
        ]
        "#<#{self.class.name}:#{object_id} #{attributes.join(', ')}>"
      end

      # Public: a more efficient implementation of import for this adapter
      def import(source_adapter)
        get_all = source_adapter.get_all
        @lock.with_write_lock { @source.replace(get_all) }
      end
    end
  end
end