Closed sfcgeorge closed 6 years ago
@sfcgeorge sounds like you have figured out more about this... at some point can we have a conversation about what you know... so we can fix.
[from chat] Sometimes the type field gets set to nil, so Hyperloop thinks it has changed (it shouldn't have) so is sent on the wire, and once in Rails saves fail, queries fail etc.
I added a NOT NULL constraint on the DB to protect the data, but that obviously doesn't stop the crashed. Then I monkyepatched Hyperloop to not change type to nil. It gets loaded fine in the first place, then can become nil for whatever reason, so the patch prevents that and seems to have mitigated the issue. Adding a puts shows type is set to nil several times around fetches.
module ReactiveRecord
class Base
def dont_update_attribute?(attribute, value)
return true if attribute == :type && value.blank? # <-- patch
return false if attributes[attribute].is_a?(DummyValue)
return false unless attributes.key?(attribute)
return false if attributes[attribute] != value
true
end
end
Note: this is treating the symptom not the cause, I don't know why Hyperloop thinks the type has changed to nil in the first place, I'm just preventing that change from being stored.
Well I believe this might be the culprit (or at least just where the nilling is happening)
# lib/reactive_record/active_record/instance_methods.rb
module ActiveRecord
module InstanceRecords
def type
@backing_record.reactive_get!(:type, nil)
end
def type=(val)
@backing_record.reactive_set!(:type, backing_record.convert(:type, val))
end
end
end
Commenting out this code gets rid of the problem, but what are these two methods actually doing @catmando ?
Edit: Commenting out that code only somehow made it happen less frequently? So nevermind...
Actually it looks like this is the cause:
# lib/reactive-record/active-record/class_methods.rb
module ActiveRecord
module ClassMethods
def _react_param_conversion(param, opt = nil)
...
if value
[assoc.attribute, {id: [value], type: [nil]}]
else
[assoc.attribute, [nil]]
end
end
end
end
I think is happening when updated records are pushed to the client. Removing the type: [nil]
seems to fix the problem, but I don't know why that is there and what it is intending to do.
I think its fixed! ab8637bc2b3a250f1e74544245375cb9806a7442
Eek. Just looked like hyper-mesh deleted a record, but actually the record just became invisible to Rails. For some reason Hyper-mesh/react must have thought the
type
field changed to nil and saved as such. Rails automatically adds to all queries likeWHERE type = 'Candidate'
so the record effectively dissappears. It is also of course a data loss bug as you no longer know what the record's STI type is, but it's not such a bad data loss bug, everything else is still there.This is the first time I've seen it happen, and I've been using Hyperloop a fair while now so it's not so easy to reproduce.
I'm going to ensure it doesn't happen in our app again by adding a not null DB constraint (which it should already have had).
The save that blanked the type