Class: Spinoza::MetaLog
- Inherits:
-
Object
- Object
- Spinoza::MetaLog
- Defined in:
- lib/spinoza/system/meta-log.rb
Overview
Model of synchronously replicated, linearizable global log, such as Zookeeper.
Defined Under Namespace
Classes: Entry
Instance Attribute Summary collapse
-
#dt_quorum ⇒ Object
readonly
Time to replicate a write to a quorum of MetaLog nodes, and for a unique sequence number to be assigned, and for that to be communicated to the writer node.
-
#dt_replicated ⇒ Object
readonly
Delay for a write to become “completely” replicated: readable at all nodes.
Instance Method Summary collapse
-
#append(value, node: raise) ⇒ Object
Append value to the MetaLog, assigning it a unique monotonically increasing ID.
-
#get(id, node: raise) ⇒ Object
Returns the value if the data has been propagated to
node
, otherwise, returns nil. -
#initialize(dt_quorum: 0.300, dt_replicated: 0.500) ⇒ MetaLog
constructor
A new instance of MetaLog.
-
#on_entry_available(actor, action) ⇒ Object
Request that, whenever a new entry is created, an event be added to the schedule that will fire at entry.time_replicated.
-
#quorum?(id) ⇒ Boolean
Returns true if the writing node knows that the data at
id
has been replicated to a quorum of nodes. - #time_quorum(id) ⇒ Object
- #time_replicated(id) ⇒ Object
Constructor Details
#initialize(dt_quorum: 0.300, dt_replicated: 0.500) ⇒ MetaLog
Returns a new instance of MetaLog.
46 47 48 49 50 51 |
# File 'lib/spinoza/system/meta-log.rb', line 46 def initialize dt_quorum: 0.300, dt_replicated: 0.500 @dt_quorum = dt_quorum @dt_replicated = dt_replicated @store = [] @replication_listeners = [] end |
Instance Attribute Details
#dt_quorum ⇒ Object (readonly)
Time to replicate a write to a quorum of MetaLog nodes, and for a unique sequence number to be assigned, and for that to be communicated to the writer node.
8 9 10 |
# File 'lib/spinoza/system/meta-log.rb', line 8 def dt_quorum @dt_quorum end |
#dt_replicated ⇒ Object (readonly)
Delay for a write to become “completely” replicated: readable at all nodes. Adjust this quantity for your network performance.
12 13 14 |
# File 'lib/spinoza/system/meta-log.rb', line 12 def dt_replicated @dt_replicated end |
Instance Method Details
#append(value, node: raise) ⇒ Object
Append value to the MetaLog, assigning it a unique monotonically increasing ID. In our use case, the value will be a key (or batch of keys) of the Log. Returns an id, which can be used to retrieve the entry in the order it was appended. The returned id should only be used to observe the model, and not used within the model itself, since the id won’t be available to the requesting process until ‘time_quorum(id)`.
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/spinoza/system/meta-log.rb', line 83 def append value, node: raise entry = Entry.new(node: node, value: value, time_quorum: node.time_now + dt_quorum, time_replicated: node.time_now + dt_replicated) @store << entry id = @store.size - 1 @replication_listeners.each do |actor, action| node.timeline << Spinoza::Event[ time: entry.time_replicated, actor: actor, action: action, id: id, node: node, value: value] end id end |
#get(id, node: raise) ⇒ Object
Returns the value if the data has been propagated to node
, otherwise, returns nil.
99 100 101 102 |
# File 'lib/spinoza/system/meta-log.rb', line 99 def get id, node: raise entry = @store[id] entry && entry.readable_at?(node) ? entry.value : nil end |
#on_entry_available(actor, action) ⇒ Object
Request that, whenever a new entry is created, an event be added to the schedule that will fire at entry.time_replicated. The event will send the method named ‘action` to `actor`, with id, node, and value arguments. Note that events fire in id order (because of the strong consistency guarantees that the meta-log’s underlying store is assumed to have).
73 74 75 |
# File 'lib/spinoza/system/meta-log.rb', line 73 def on_entry_available actor, action @replication_listeners << [actor, action] end |
#quorum?(id) ⇒ Boolean
Returns true if the writing node knows that the data at id
has been replicated to a quorum of nodes.
55 56 57 58 |
# File 'lib/spinoza/system/meta-log.rb', line 55 def quorum? id entry = @store[id] entry && entry.quorum? end |
#time_quorum(id) ⇒ Object
60 61 62 |
# File 'lib/spinoza/system/meta-log.rb', line 60 def time_quorum id @store[id].time_quorum end |
#time_replicated(id) ⇒ Object
64 65 66 |
# File 'lib/spinoza/system/meta-log.rb', line 64 def time_replicated id @store[id].time_replicated end |