[Spice-devel] File Transfer API

Marc-André Lureau mlureau at redhat.com
Wed Sep 16 09:33:42 PDT 2015


Hi

----- Original Message -----
> So, spice-gtk has supported file transfers from client to guest for
> quite a while. But there's a longstanding issue that the user has no
> feedback about whether the file is actually being transferred, or how
> long it will take. The only real feedback that a user gets is after the
> file transfer is completed: the vdagent will generally open a file
> browser window to reveal the transferred file.
> 
> So I was poking around a bit with adding a file transfer progress
> indication to virt-viewer, and I found that the file transfer API in
> spice-gtk does not make this very easy. The main API involved here is
> this:
> 
> void spice_main_file_copy_async(SpiceMainChannel *channel,
>                                 GFile **sources,
>                                 GFileCopyFlags flags,
>                                 GCancellable *cancellable,
>                                 GFileProgressCallback progress_callback,
>                                 gpointer progress_callback_data,
>                                 GAsyncReadyCallback callback,
>                                 gpointer user_data);
> 
> At first glance, it looks like this gives us everything we need, but
> there are a few issues with it. The main ones are:

Just want to mention this API was originally designed with single file copy in mind (at this time no plan for multiple files), and there was no support for monitoring/notification of progress from listeners either (only the caller could get the progress).

> 
> 
> 1. It's possible to pass an array of files to be transferred, but the
> progress_callback is called for each file separately. But the
> GFileProgressCallback function signature does not provide any way for
> the caller to determine which file a given progress_callback() call is
> associated with. For example, if you tried to transfer 2 different files
> with sizes 100 and 200, you might get the following:
> - progress_callback(0, 100, progress_callback_data)
> - progress_callback(0, 200, progress_callback_data)
> - progress_callback(50, 100, progress_callback_data)
> - progress_callback(50, 200, progress_callback_data)
> - progress_callback(100, 100, progress_callback_data)
> - progress_callback(100, 200, progress_callback_data)
> - progress_callback(150, 200, progress_callback_data)
> - progress_callback(200, 200, progress_callback_data)
> 
> In this case, you could apply some heuristics to figure out which
> callback applied to which file by examining the file sizes, but that is
> not ideal, and is not always going to work. A workaround for this is to
> sum up total progress internally and pass these values to the
> progress_callback. In that case, you'd get something more like this:
> - progress_callback(0, 300, progress_callback_data)
> - progress_callback(0, 300, progress_callback_data)
> - progress_callback(50, 300, progress_callback_data)
> - progress_callback(100, 300, progress_callback_data)
> - progress_callback(150, 300, progress_callback_data)
> - progress_callback(200, 300, progress_callback_data)
> - progress_callback(250, 300, progress_callback_data)
> - progress_callback(300, 300, progress_callback_data)
> 
> That seems OK, but see #3 below as to why this isn't really a full
> solution.
> 
> 
> 
> 2. spice_main_file_copy_async() looks like a single transaction, so you
> would expect it to call 'callback' after all files are finished being
> transferred. But in reality, 'callback' is called once for each file
> that is being transferred. This makes it difficult for the application
> to keep track of the status of the entire transaction. It would be much
> better to make it behave like every other gio-style async API and have a
> single _async() call paired to a single _finish() call.
> 
> 
> 
> 3. Even if the spice_main_file_copy_async() API mentioned above did not
> have any problems, it's difficult for an application to make use of it
> if they also use the SpiceDisplay widget. This is because the
> SpiceDisplay widget automatically handles drag-and-drop of files onto
> the display. When a file is dropped, it immediately starts a file
> transfer. This means that the application cannot use in its own
> 'progress_callback' or 'callback' functions in order to monitor and
> display the file transfer progress. There's currently no way to disable
> this automatic handling of drag-and-drop on the widget.
> 
> 
> ==========
> 
> We could deprecate this API, but I don't want to remove or break public
> API. So we still need to support transfers created with the current
> function. I'd like to propose a complementary API:
> 
> Add a new public object SpiceFileTransferTask with the following
> characteristics:
>  - it represents the transfer of a single file
>  - it has a "progress" property, which represents the percentage of the
> file that has been transferred. The application can connect to the
> "notify::progress" signal to be notified when the progress of a transfer
> changes.
>  - it has a "finished" signal so that the application can tell when the
> transfer of that file has completed
>  - it has a "filename" property so that the application can display the
> filename next to the progress of the transfer if desired
>  - it has a "cancel()" method, so that an application can cancel an
> individual file transfer[0]
> 
> In addition to this new object, add a "new-file-transfer" signal to
> SpiceMainChannel. This signal will be emitted whenever a new file
> transfer task has been initiated (presumably by the drag-and-drop
> handler of the SpiceDisplay widget).
> 
> This should allow us to keep our API stable and still allow applications
> to monitor and display feedback of file transfers. Objections? Alternate
> suggestions?
> 
> Since you managed to read this whole long-winded message, here's a
> little screencast of a preliminary implementation in spicy using the
> above approach:
> http://people.freedesktop.org/~jjongsma/spicy-file-transfer-progress.ogv
> 
> Thanks,
> Jonathon
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list