예제 #1
0
    def _submit_ranged_download_request(self, client, config, osutil,
                                        request_executor, io_executor,
                                        download_output_manager,
                                        transfer_future, bandwidth_limiter):
        call_args = transfer_future.meta.call_args

        # Get the needed progress callbacks for the task
        progress_callbacks = get_callbacks(transfer_future, 'progress')

        # Get a handle to the file that will be used for writing downloaded
        # contents
        fileobj = download_output_manager.get_fileobj_for_io_writes(
            transfer_future)

        # Determine the number of parts
        part_size = config.multipart_chunksize
        num_parts = calculate_num_parts(transfer_future.meta.size, part_size)

        # Get any associated tags for the get object task.
        get_object_tag = download_output_manager.get_download_task_tag()

        # Callback invoker to submit the final io task once all downloads
        # are complete.
        finalize_download_invoker = CountCallbackInvoker(
            self._get_final_io_task_submission_callback(
                download_output_manager, io_executor))
        for i in range(num_parts):
            # Calculate the range parameter
            range_parameter = calculate_range_parameter(
                part_size, i, num_parts)

            # Inject the Range parameter to the parameters to be passed in
            # as extra args
            extra_args = {'Range': range_parameter}
            extra_args.update(call_args.extra_args)
            finalize_download_invoker.increment()
            # Submit the ranged downloads
            self._transfer_coordinator.submit(
                request_executor,
                GetObjectTask(
                    transfer_coordinator=self._transfer_coordinator,
                    main_kwargs={
                        'client': client,
                        'bucket': call_args.bucket,
                        'key': call_args.key,
                        'fileobj': fileobj,
                        'extra_args': extra_args,
                        'callbacks': progress_callbacks,
                        'max_attempts': config.num_download_attempts,
                        'start_index': i * part_size,
                        'download_output_manager': download_output_manager,
                        'io_chunksize': config.io_chunksize,
                        'bandwidth_limiter': bandwidth_limiter
                    },
                    done_callbacks=[finalize_download_invoker.decrement]),
                tag=get_object_tag)
        finalize_download_invoker.finalize()
예제 #2
0
 def _submit_ranged_get_object_jobs(self, download_file_request,
                                    temp_filename, size):
     part_size = self._transfer_config.multipart_chunksize
     num_parts = calculate_num_parts(size, part_size)
     self._notify_jobs_to_complete(download_file_request.transfer_id,
                                   num_parts)
     for i in range(num_parts):
         offset = i * part_size
         range_parameter = calculate_range_parameter(
             part_size, i, num_parts)
         get_object_kwargs = {'Range': range_parameter}
         get_object_kwargs.update(download_file_request.extra_args)
         self._submit_get_object_job(
             transfer_id=download_file_request.transfer_id,
             bucket=download_file_request.bucket,
             key=download_file_request.key,
             temp_filename=temp_filename,
             offset=offset,
             extra_args=get_object_kwargs,
             filename=download_file_request.filename,
         )
예제 #3
0
 def test_calculate_num_parts_not_divisible(self):
     self.assertEqual(calculate_num_parts(size=3, part_size=2), 2)