zipline icon indicating copy to clipboard operation
zipline copied to clipboard

Fixes rails 7.1.2 compatibility

Open joker-777 opened this issue 1 year ago • 4 comments

  • Buffer#to_ary now calls "each" without a block when the body doesn't have a 'to_ary' method
  • fixes https://github.com/fringd/zipline/issues/91

joker-777 avatar Dec 12 '23 13:12 joker-777

I'll save some time to anyone trying to find the rails diff which resulted in this

self.response_body = zip_generator within gem calls response_body= method within rails, which calls body= on Response object, which results in assigning of Buffer built based of unchanged ZipGenerator to stream attribute of buffer

While responding Puma checks whether response body responds to to_ary and it does since this change and this change in Rails repo. Then this to_ary method is called on ZipGenerator. However Puma does additional check on the result of this method with array_body.is_a?(Array) and falls back to body = res_body if this check doesn't pass. I believe this PR only works due to Puma making this check and much better option would be supporting call of ZipGenerator#each w/o block. Rack also supports call method for "streaming body", but I'm not sure it will work, with Buffer always responding to to_ary :thinking:

@joker-777, please correct if I'm wrong

fizvlad avatar Jan 04 '24 21:01 fizvlad

I'll save some time to anyone trying to find the rails diff which resulted in this

self.response_body = zip_generator within gem calls response_body= method within rails, which calls body= on Response object, which results in assigning of Buffer built based of unchanged ZipGenerator to stream attribute of buffer

While responding Puma checks whether response body responds to to_ary and it does since this change and this change in Rails repo. Then this to_ary method is called on ZipGenerator. However Puma does additional check on the result of this method with array_body.is_a?(Array) and falls back to body = res_body if this check doesn't pass. I believe this PR only works due to Puma making this check and much better option would be supporting call of ZipGenerator#each w/o block. Rack also supports call method for "streaming body", but I'm not sure it will work, with Buffer always responding to to_ary 🤔

@joker-777, please correct if I'm wrong

@fizvlad created a new PR which is using your approach https://github.com/fringd/zipline/pull/93

symmetreDenis avatar Jan 08 '24 09:01 symmetreDenis

we cool to close this one now that we merged #93 ?

fringd avatar Feb 02 '24 23:02 fringd

The change in this PR might not work as desired. The Rack SPEC for Rack 3 (to_ary is a modern addition I believe) specifies in https://github.com/rack/rack/blob/main/SPEC.rdoc#enumerable-body- that if a body responds to to_ary it must actually do something sensible. There is a likelihood that if a server finds out you respond to to_ary it will as well call it, and not call each at all. Rails removed to_ary also for that reason - https://github.com/rails/rails/pull/44953

What is in place currently (support each and only each) is correct. Allowing blockless each was a workaround for the Rails issue misinterpreting to_ary but it can be kept in place since Rails did have a release with that broken to_ary.

julik avatar Feb 04 '24 22:02 julik

we cool to close this one now that we merged https://github.com/fringd/zipline/pull/93 ?

@fringd yes, do close please 😄 this will cause breakage if merged, so better not have it hanging around

julik avatar Feb 12 '24 13:02 julik