soveran / nest

Generate nested namespaced keys for key-value databases.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

oh i totally missed the notification from @soveran. sorry for that

but @elskwid outlined the case which i have, thanks

@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.

@dreyks @elskwid Thanks a lot for your help!