Class: ReactiveRecord::Broadcast
- Defined in:
- lib/reactive_record/broadcast.rb
Defined Under Namespace
Classes: SendPacket
Instance Attribute Summary collapse
-
#record ⇒ Object
readonly
private.
Class Method Summary collapse
- .after_commit(operation, model) ⇒ Object
- .in_transit ⇒ Object
- .open_channels ⇒ Object
- .send_to_server(operation, data) ⇒ Object
- .to_self(record, data = {}) ⇒ Object
Instance Method Summary collapse
- #complete! ⇒ Object
- #destroyed? ⇒ Boolean
-
#initialize(id) ⇒ Broadcast
constructor
A new instance of Broadcast.
- #klass ⇒ Object
- #local(operation, record, data) ⇒ Object
- #merge_current_values(br) ⇒ Object
- #new? ⇒ Boolean
- #receive(params) {|complete! if | ... } ⇒ Object
- #record_with_current_values ⇒ Object
- #record_with_new_values ⇒ Object
- #to_s ⇒ Object
Constructor Details
Instance Attribute Details
#record ⇒ Object (readonly)
private
117 118 119 |
# File 'lib/reactive_record/broadcast.rb', line 117 def record @record end |
Class Method Details
.after_commit(operation, model) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/reactive_record/broadcast.rb', line 4 def self.after_commit(operation, model) Hyperloop::InternalPolicy.regulate_broadcast(model) do |data| if !Hyperloop.on_server? && Hyperloop::Connection.root_path send_to_server(operation, data) else SendPacket.run(data, operation: operation) end end rescue ActiveRecord::StatementInvalid => e raise e unless e. == "Could not find table 'hyperloop_connections'" end |
.in_transit ⇒ Object
123 124 125 |
# File 'lib/reactive_record/broadcast.rb', line 123 def self.in_transit @in_transit ||= Hash.new { |h, k| h[k] = new(k) } end |
.open_channels ⇒ Object
119 120 121 |
# File 'lib/reactive_record/broadcast.rb', line 119 def self.open_channels @open_channels ||= Set.new end |
.send_to_server(operation, data) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/reactive_record/broadcast.rb', line 16 def self.send_to_server(operation, data) salt = SecureRandom.hex = Hyperloop.(salt, data[:channel], data[:broadcast_id]) raise 'no server running' unless Hyperloop::Connection.root_path SendPacket.remote( Hyperloop::Connection.root_path, data, operation: operation, salt: salt, authorization: ) end |
.to_self(record, data = {}) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/reactive_record/broadcast.rb', line 64 def self.to_self(record, data = {}) # simulate incoming packet after a local save operation = if record.new? :create elsif record.destroyed? :destroy else :change end dummy_broadcast = new.local(operation, record, data) record.backing_record.sync! data unless operation == :destroy ReactiveRecord::Collection.sync_scopes dummy_broadcast end |
Instance Method Details
#complete! ⇒ Object
164 165 166 |
# File 'lib/reactive_record/broadcast.rb', line 164 def complete! self.class.in_transit.delete @id end |
#destroyed? ⇒ Boolean
103 104 105 |
# File 'lib/reactive_record/broadcast.rb', line 103 def destroyed? @destroyed end |
#klass ⇒ Object
107 108 109 |
# File 'lib/reactive_record/broadcast.rb', line 107 def klass Object.const_get(@klass) end |
#local(operation, record, data) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/reactive_record/broadcast.rb', line 134 def local(operation, record, data) @destroyed = operation == :destroy @is_new = operation == :create @klass = record.class.name @record = data record.backing_record.destroyed = false @record.merge!(id: record.id) if record.id record.backing_record.destroyed = @destroyed @backing_record = record.backing_record attributes = record.backing_record.attributes data.each do |k, v| next if klass.reflect_on_association(k) || attributes[k] == v @previous_changes[k] = [attributes[k], v] end self end |
#merge_current_values(br) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/reactive_record/broadcast.rb', line 168 def merge_current_values(br) current_values = Hash[*@previous_changes.collect do |attr, values| value = attr == :id ? record[:id] : values.first if br.attributes.key?(attr) && br.attributes[attr] != br.convert(attr, value) && br.attributes[attr] != br.convert(attr, values.last) puts "warning #{attr} has changed locally - will force a reload.\n"\ "local value: #{br.attributes[attr]} remote value: #{br.convert(attr, value)}->#{br.convert(attr, values.last)}" return nil end [attr, value] end.compact.flatten].merge(br.attributes) klass._react_param_conversion(current_values) end |
#new? ⇒ Boolean
99 100 101 |
# File 'lib/reactive_record/broadcast.rb', line 99 def new? @is_new end |
#receive(params) {|complete! if | ... } ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/reactive_record/broadcast.rb', line 151 def receive(params) @destroyed = params.operation == :destroy @is_new = params.operation == :create @channels ||= Hyperloop::IncomingBroadcast.open_channels.intersection params.channels #raise 'synchromesh security violation' unless @channels.include? params.channels @received << params.channel @klass ||= params.klass @record.merge! params.record @previous_changes.merge! params.previous_changes @backing_record = ReactiveRecord::Base.exists?(klass, params.record[:id]) yield complete! if @channels == @received end |
#record_with_current_values ⇒ Object
78 79 80 81 82 83 84 85 86 87 |
# File 'lib/reactive_record/broadcast.rb', line 78 def record_with_current_values ReactiveRecord::Base.load_data do backing_record = @backing_record || klass.find(record[:id]).backing_record if destroyed? backing_record.ar_instance else merge_current_values(backing_record) end end end |
#record_with_new_values ⇒ Object
89 90 91 92 93 94 95 96 97 |
# File 'lib/reactive_record/broadcast.rb', line 89 def record_with_new_values klass._react_param_conversion(record).tap do |ar_instance| if destroyed? ar_instance.backing_record.destroy_associations elsif new? ar_instance.backing_record.initialize_collections end end end |
#to_s ⇒ Object
111 112 113 |
# File 'lib/reactive_record/broadcast.rb', line 111 def to_s "klass: #{klass} record: #{record} new?: #{new?} destroyed?: #{destroyed?}" end |