Module: EntityStore

Included in:
Controls::EntityStore::NoCategory::Example, Substitute
Defined in:
lib/entity_store/log.rb,
lib/entity_store/substitute.rb,
lib/entity_store/controls/id.rb,
lib/entity_store/entity_store.rb,
lib/entity_store/controls/entity.rb,
lib/entity_store/controls/reader.rb,
lib/entity_store/controls/record.rb,
lib/entity_store/controls/message.rb,
lib/entity_store/controls/version.rb,
lib/entity_store/controls/category.rb,
lib/entity_store/controls/snapshot.rb,
lib/entity_store/controls/specifier.rb,
lib/entity_store/controls/projection.rb,
lib/entity_store/controls/stream_name.rb,
lib/entity_store/controls/entity_store.rb,
lib/entity_store/controls/snapshot_interval.rb

Defined Under Namespace

Modules: Build, Controls, EntityMacro, ProjectionMacro, ReaderMacro, SnapshotMacro, SpecifierMacro Classes: Log, Substitute

Constant Summary collapse

Error =
Class.new(RuntimeError)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(cls) ⇒ Object



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
# File 'lib/entity_store/entity_store.rb', line 4

def self.included(cls)
  cls.class_exec do
    include Configure
    include Dependency
    include TemplateMethod

    include Log::Dependency
    include Messaging::Category

    substitute_class = Class.new(Substitute)

    substitute_class.send :define_method, :entity_class do
      cls.entity_class
    end

    const_set :Substitute, substitute_class

    attr_accessor :session
    attr_accessor :new_entity_probe

    dependency :cache, EntityCache

    configure :store

    attr_accessor :category
    attr_accessor :specifier
    attr_accessor :snapshot_interval

    template_method :reader_class
    template_method :projection_class
    template_method :reader_batch_size
    template_method :snapshot_class

    template_method :configure

    extend Build
    extend EntityMacro
    extend ProjectionMacro
    extend ReaderMacro
    extend SnapshotMacro
    extend SpecifierMacro
  end
end

Instance Method Details

#delete_cache_record(id) ⇒ Object



216
217
218
# File 'lib/entity_store/entity_store.rb', line 216

def delete_cache_record(id)
  cache.internal_store.delete(id)
end

#fetch(id, include: nil) ⇒ Object Also known as: project



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/entity_store/entity_store.rb', line 178

def fetch(id, include: nil)
  logger.trace(tag: :fetch) { "Fetching entity (ID: #{id.inspect}, Entity Class: #{entity_class.name})" }

  res = get(id, include: include)

  if res.nil?
    res = new_entity
  end

  if res.is_a?(Array) && res[0].nil?
    res[0] = new_entity
  end

  logger.info(tag: :fetch) { "Fetch entity done (ID: #{id.inspect}, Entity Class: #{entity_class.name})" }

  res
end

#get(id, include: nil, &probe_action) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/entity_store/entity_store.rb', line 106

def get(id, include: nil, &probe_action)
  logger.trace(tag: :get) { "Getting entity (ID: #{id.inspect}, Entity Class: #{entity_class.name})" }

  record = cache.get id

  if record
    entity = record.entity
    version = record.version
    persisted_version = record.persisted_version
    persisted_time = record.persisted_time
  else
    entity = new_entity
  end

  current_version = refresh(entity, id, version, &probe_action)

  unless current_version.nil?
    record = cache.put(
      id,
      entity,
      current_version,
      persisted_version: persisted_version,
      persisted_time: persisted_time
    )
  end

  logger.info(tag: :get) { "Get entity done (ID: #{id.inspect}, Entity Class: #{entity_class.name}, Version: #{record&.version.inspect}, Time: #{record&.time.inspect})" }
  logger.info(tags: [:data, :entity]) { entity.pretty_inspect }

  EntityCache::Record.destructure(record, include)
end

#get_version(id) ⇒ Object



173
174
175
176
# File 'lib/entity_store/entity_store.rb', line 173

def get_version(id)
  _, version = get id, include: :version
  version
end

#new_entityObject



197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/entity_store/entity_store.rb', line 197

def new_entity
  entity = nil
  if entity_class.respond_to? :build
    entity = entity_class.build
  else
    entity = entity_class.new
  end

  unless new_entity_probe.nil?
    new_entity_probe.(entity)
  end

  entity
end

#next_position(position) ⇒ Object



165
166
167
168
169
170
171
# File 'lib/entity_store/entity_store.rb', line 165

def next_position(position)
  unless position.nil?
    position + 1
  else
    nil
  end
end

#refresh(entity, id, current_position, &probe_action) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/entity_store/entity_store.rb', line 138

def refresh(entity, id, current_position, &probe_action)
  logger.trace(tag: :refresh) { "Refreshing (ID: #{id.inspect}, Entity Class: #{entity_class.name}, Current Position #{current_position.inspect})" }
  logger.trace(tags: [:data, :entity]) { entity.pretty_inspect }

  stream_name = self.stream_name(id)

  start_position = next_position(current_position)

  project = projection_class.build(entity)

  logger.trace(tag: :refresh) { "Reading (Stream Name: #{stream_name}, Position: #{current_position})" }
  reader_class.(stream_name, position: start_position, batch_size: reader_batch_size, session: session) do |event_data|
    project.(event_data)
    current_position = event_data.position

    unless probe_action.nil?
      probe_action.(event_data)
    end
  end
  logger.debug(tag: :refresh) { "Read (Stream Name: #{stream_name}, Position: #{current_position.inspect})" }

  logger.debug(tag: :refresh) { "Refreshed (ID: #{id.inspect}, Entity Class: #{entity_class.name}, Current Position: #{current_position.inspect})" }
  logger.debug(tags: [:data, :entity]) { entity.pretty_inspect }

  current_position
end

#stream_name(id) ⇒ Object



212
213
214
# File 'lib/entity_store/entity_store.rb', line 212

def stream_name(id)
  MessageStore::StreamName.stream_name(category, id)
end