-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change open to use Down.open #8
Comments
@janko-m I had a new look at this and signed URLs on GCS requires a service account key. You cant get one with a standard account, so it will fail in many cases. |
@renchap I just pushed a new version of Down which allows Down.open("http://example.com/image.jpg", {"Authorization" => "..."}) |
I recently thought of one trick that would downloading on-demand, but still allow you to use the def open(id)
read_pipe, write_pipe = IO.pipe
Thread.new do
begin
storage_api.get_object(@bucket, object_name(id), download_dest: write_pipe)
ensure
write_pipe.close
end
end
chunks = Enumerator.new { |y| y << read_pipe.readpartial(16*1024) until read_pipe.eof? }
object = storage_api.get_object(@bucket, object_name(id)) # hopefully not providing :download_dest makes a HEAD request?
Down::ChunkedIO.new(
chunks: chunks,
size: object.size,
on_close: -> { read_pipe.close }, # will cause download to abort with an Errno::EPIPE, and google-api-client will hopefully clean up
)
end I considered doing the same with in the S3 storage, but considering that aws-sdk has the ability to stream chunks as they are downloaded if you pass a block to def open(id)
io = Down::ChunkedIO.new(chunks: (object = object(id)).enum_for(:get))
io.size = object.content_length # Down::ChunkedIO retrieves first chunk on initialization, so Aws::S3::Object#content_length is populated now
io
end |
@renchap With my #16 PR, I tried:
The linter tests broke with:
I'm not sure of the intent, so I'll leave #16 as-is, but seems like this one is not far off once that is merged. |
Btw, I wouldn't use class ProcIO
def initialize(&proc)
@proc = proc
end
def write(data)
@proc.call(data)
data.bytesize # it's ruby convention to return bytes written, it's required by methods like IO.copy_stream
end
end
def open(id)
file = get_file(id)
chunks = Enumerator.new do |yielder|
proc_io = ProcIO.new { |data| yielder << data }
file.download(proc_io)
end
Down::ChunkedIO.new(
chunks: chunks,
size: file.size,
data: { file: file } # so the user can access it if they want to
)
end |
Note that the above should be possible because a while ago I expanded what can be the |
This will make the storage work well with the restore_metadata Shrine plugin, as it will allow extracting metadata by downloading only a portion of the file content. Closes renchap#8
This will make the storage work well with the restore_metadata Shrine plugin, as it will allow extracting metadata by downloading only a portion of the file content. Closes renchap#8
* Implement #open using Down::ChunkedIO This will make the storage work well with the restore_metadata Shrine plugin, as it will allow extracting metadata by downloading only a portion of the file content. Closes #8 * Add ProcIO#flush required by google-api-client * Open test image file in binary mode That way retrieved content will in binary encoding, which is generally safer to use cross-platform. It also avoids comparing the same content in binary and UTF-8 encoding in tests, which will differ even if the bytes themselves are the same. * Don't verify downloaded data in #open
From Janko :
This will require #7 first
The text was updated successfully, but these errors were encountered: