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 Virtual

    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

    virtual :reader_class
    virtual :projection_class
    virtual :reader_batch_size
    virtual :snapshot_class
    virtual :snapshot_interval

    virtual :configure

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

Instance Method Details

#delete_cache_record(id) ⇒ Object



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

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

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



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

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



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

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



170
171
172
173
# File 'lib/entity_store/entity_store.rb', line 170

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

#new_entityObject



194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/entity_store/entity_store.rb', line 194

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



162
163
164
165
166
167
168
# File 'lib/entity_store/entity_store.rb', line 162

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

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



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

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



209
210
211
# File 'lib/entity_store/entity_store.rb', line 209

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