Class: Spinoza::Log

Inherits:
Object
  • Object
show all
Defined in:
lib/spinoza/system/log.rb

Overview

Model of asynchronously replicated global log, such as Cassandra. We assume that each node in our system has a replica providing this service.

Defined Under Namespace

Classes: Entry, KeyConflictError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dt_durable: 0.300, dt_replicated: 0.500) ⇒ Log

Returns a new instance of Log.



52
53
54
55
56
# File 'lib/spinoza/system/log.rb', line 52

def initialize dt_durable: 0.300, dt_replicated: 0.500
  @dt_durable = dt_durable
  @dt_replicated = dt_replicated
  @store = {}
end

Instance Attribute Details

#dt_durableObject (readonly)

Delay for a write to become durable on “enough” replicas, from the point of view of the writing node. Adjust this quantity for your definition of durable and your network performance.



9
10
11
# File 'lib/spinoza/system/log.rb', line 9

def dt_durable
  @dt_durable
end

#dt_replicatedObject (readonly)

Delay for a write to become “completely” replicated: readable at all nodes. Adjust this quantity for your network performance.



13
14
15
# File 'lib/spinoza/system/log.rb', line 13

def dt_replicated
  @dt_replicated
end

Instance Method Details

#durable?(key) ⇒ Boolean

Returns true if the writing node believes the data at key is durable.

Returns:

  • (Boolean)


59
60
61
62
# File 'lib/spinoza/system/log.rb', line 59

def durable? key
  entry = @store[key]
  entry && entry.durable?
end

#read(key, node: raise) ⇒ Object

Returns the value if the data has been propagated to node, otherwise, returns nil.



91
92
93
94
# File 'lib/spinoza/system/log.rb', line 91

def read key, node: raise
  entry = @store[key]
  entry && entry.readable_at?(node) ? entry.value : nil
end

#time_durable(key) ⇒ Object



64
65
66
# File 'lib/spinoza/system/log.rb', line 64

def time_durable key
  @store[key].time_durable
end

#time_replicated(key) ⇒ Object



76
77
78
# File 'lib/spinoza/system/log.rb', line 76

def time_replicated key
  @store[key].time_replicated
end

#when_durable(key, **event_opts) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/spinoza/system/log.rb', line 68

def when_durable key, **event_opts
  entry = @store[key]
  entry.node.timeline.schedule Spinoza::Event[
    time: entry.time_durable,
    **event_opts
  ]
end

#write(key, value, node: raise) ⇒ Object

Returns the entry.

Raises:



81
82
83
84
85
86
87
# File 'lib/spinoza/system/log.rb', line 81

def write key, value, node: raise
  raise KeyConflictError if @store[key] or not value
  @store[key] =
    Entry.new node: node, value: value,
      time_durable: node.time_now + dt_durable,
      time_replicated: node.time_now + dt_replicated
end