Issues when running with Activesupport
dreyks opened this issue · comments
Activesupport overrides Object#to_json
so that it calls Object#as_json
. The latter however looks for to_hash
method and if not found just grabs all the instance variables. This leads to Nest.initialize('foo').to_json
returning a ton of garbage instead of a key, because it also appends @rc
The issue can be solved by adding Nest#to_json
explicitly so that it does to_s.to_json
for example
UPD: this won't work. The solutions are to add Nest#to_hash
or Nest#as_json
to return @ns
, both of which being kinda meh since it's not really a hash...
This is ok for a monkeypatch workaround though =)
Hey @dreyks, I'd like to look into this issue. What would be the use case where this happens?
@soveran we ran into this issue as well. We have an Ohm::Model
defined in a rails project and are seeing errors when calling #delete
. This worked previously because the Nido
class inherited from String
which serializes as the string when to_json
is called.
Now, with Nest
the problem manifests itself, for example, when the model data is serialized to JSON on the way into the lua delete.
{
"name" => model.name,
"id" => id,
"key" => key
}.to_json
The default ActiveSupport behavior results in JSON that looks like:
=> "{\"name\":\"MyModel\",\"id\":\"1\",\"key\":{\"ns\":\"MyModel:1\",\"rc\":{\"url\":\"redis://127.0.0.1:6379\",\"client\":{\"semaphore\":{},\"connection\":{},\"uri\":{\"scheme\":\"redis\",\"user\":null,\"password\":null,\"host\":\"127.0.0.1\",\"port\":6379,\"path\":\"\",\"query\":null,\"opaque\":null,\"fragment\":null,\"parser\":{\"regexp\":{\"SCHEME\":\"(?-mix:\\\\A[A-Za-z][A-Za-z0-9+\\\\-.]*\\\\z)\",\"USERINFO\":\"(?-mix:\\\\A(?:%\\\\h\\\\h|[!$&-.0-;=A-Z_a-z~])*\\\\z)\",\"HOST\":\"(?-mix:\\\\A(?:(?<IP-literal>\\\\[(?:(?<IPv6address>(?:\\\\h{1,4}:){6}(?<ls32>\\\\h{1,4}:\\\\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5]|\\\\d)\\\\.\\\\g<dec-octet>\\\\.\\\\g<dec-octet>\\\\.\\\\g<dec-octet>))|::(?:\\\\h{1,4}:){5}\\\\g<ls32>|\\\\h{,4}::(?:\\\\h{1,4}:){4}\\\\g<ls32>|(?:(?:\\\\h{1,4}:)?\\\\h{1,4})?::(?:\\\\h{1,4}:){3}\\\\g<ls32>|(?:(?:\\\\h{1,4}:){,2}\\\\h{1,4})?::(?:\\\\h{1,4}:){2}\\\\g<ls32>|(?:(?:\\\\h{1,4}:){,3}\\\\h{1,4})?::\\\\h{1,4}:\\\\g<ls32>|(?:(?:\\\\h{1,4}:){,4}\\\\h{1,4})?::\\\\g<ls32>|(?:(?:\\\\h{1,4}:){,5}\\\\h{1,4})?::\\\\h{1,4}|(?:(?:\\\\h{1,4}:){,6}\\\\h{1,4})?::)|(?<IPvFuture>v\\\\h+\\\\.[!$&-.0-;=A-Z_a-z~]+))\\\\])|\\\\g<IPv4address>|(?<reg-name>(?:%\\\\h\\\\h|[!$&-.0-9;=A-Z_a-z~])*))\\\\z)\",\"ABS_PATH\":\"(?-mix:\\\\A\\\\/(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~])*(?:\\\\/(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~])*)*\\\\z)\",\"REL_PATH\":\"(?-mix:\\\\A(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~])+(?:\\\\/(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~])*)*\\\\z)\",\"QUERY\":\"(?-mix:\\\\A(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~\\\\/?])*\\\\z)\",\"FRAGMENT\":\"(?-mix:\\\\A(?:%\\\\h\\\\h|[!$&-.0-;=@-Z_a-z~\\\\/?])*\\\\z)\",\"OPAQUE\":\"(?-mix:\\\\A(?:[^\\\\/].*)?\\\\z)\",\"PORT\":\"(?-mix:\\\\A[\\\\x09\\\\x0a\\\\x0c\\\\x0d ]*\\\\d*[\\\\x09\\\\x0a\\\\x0c\\\\x0d ]*\\\\z)\"}}},\"timeout\":10000000},\"buffer\":{}}}}"
When what we want is:
=> "{\"name\":\"MyModel\",\"id\":\"1\",\"key\":\"MyModel:1\"}"
Does this help narrow down the issue? I can provide more information if needed. We're going to patch Nest
with #as_json
which will delegate to #to_s
for the time being.
@soveran here's the error we see from Ohm
indicating that the key
is not working for the concatenate
call in the delete
script.
RuntimeError: ERR Error running script (call to f_04b618fcd770c78a6ac701a83bb76579433e9fed):
@user_script:27: user_script:27: attempt to concatenate field 'key' (a table value)
RuntimeError: ERR Error running script (call to f_04b618fcd770c78a6ac701a83bb76579433e9fed): @user_script:27: user_script:27: attempt to concatenate field 'key' (a table value)
File ".../bundle/ruby/2.3.0/gems/redic-1.5.0/lib/redic.rb" line 43 in call!
File ".../bundle/ruby/2.3.0/gems/ohm-3.1.0/lib/ohm.rb" line 1402 in script
File ".../bundle/ruby/2.3.0/gems/ohm-3.1.0/lib/ohm.rb" line 1375 in delete
@dreyks @elskwid Thanks a lot for your help! I was able to install activesupport and reproduce the error. I released Ohm 3.1.1 with a small fix: instead of using "key" => key
in delete
, it now uses "key" => key.to_s
. That fixed the serialization problem. That doesn't solve the serialization issue when using Nest independently, and I agree with @dreyks that adding to_hash
or as_json
looks very alien. One option looking forward could be to make Nest
inherit from String
once again. Please let me know if Ohm 3.1.1 solves the issues you were having, and also let me know if you need the other fix for Nest itself. Thanks!
thanks! yeah i'm only using Nest as a part of Ohm, so this will fix it for me
@soveran saw the fix on Ohm. That will also work perfectly in my case. For what it's worth, I agree that adding methods is not needed nor desired.
Thank you so much for your attention and the fine libraries.