[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
| Re: [ecf-dev] Exception propagation during file transfer | 
Hi Thomas,
Some comments below.
Thomas Hallgren wrote:
Hi Scott,
My use-case is perhaps a bit out of the ordinary. Here's what I want 
to do:
During a resolution/materialization from Buckminster, several jobs are 
spawned that are tasked with different types of downloads. It is 
common that the transitive resolution of one component results in 
parallel resolution of its dependencies. During the resolution there 
are junctions where things must come together so it's common to wait 
for a family of jobs to complete.
As you can see, my setup is not completely asynchronous. I need to 
know about completed downloads since the artifacts that are downloaded 
have an impact on how the resolution is progressing. One thing that 
has a big impact is of course if a download is failing. The failures 
are always propagated and will typically result in the failure of a 
node higher up in the resolution chain which in turns cancels not just 
the failing job, but also all parallel jobs extending from that same 
point.
So in essence, I need two things. I need to be able to catch 
exceptions during download and I need to be able to wait for a 
download to complete and then deal with the exception that caused the 
termination (if any). From the looks of it, this is partly 
implemented. An exception is indeed passed on when I receive the 
IIncomingFileTransferReceiveDoneEvent. But there's no way for me to 
set it (unless I throw a RuntimeException).
It's not totally clear to me how to wait for a completion. Ideally, if 
the FileTransferJob was accessible and if it did something intelligent 
and configurable with the Job.belongsTo(Object family) method, then it 
would be possible to assign a job family to it. 
Yes, I think some kind of access to the FileTransferJob would be a good 
idea (to support your use case and possibly others). 
That would make it very easy to wait for the completion of a set of 
parallel downloads.
Yes.  Some thoughts on design/approach (please give ideas about how/how 
well this addresses your use case):
1) IFileTransfer could be enhanced with a method
Job IFileTransfer.getJob()
...so that after the event.receive(OutputStream) successfully completed, 
the IFileTransfer.getJob() would return a non-null Job instance.  
Clients could then call job.join()
2) API could be added (directly on or adapter for 
IRetrieveFileTransferContainerAdapter) to allow the Job instance to be 
constructed by clients...which would allow them to create a subclass of 
FileTransferJob that overrode the
boolean FileTransferJob.belongsTo(Object)
I think I would prefer 2, because it gives clients more control (i.e. 
they can create whatever Job instance type they prefer, before 
initiating file transfer).
So perhaps a method like this could be added to 
IRetrieveFileTransferContainerAdapter
public void setJobFactory(IRetrieveFileTransferJobFactory factory);
Where IRetrieveFileTransferJobFactory factory looked something like this:
public interface IRetrieveFileTransferJobFactory {
public FileTransferJob createFileTransferJob(IFileID fileID);
}
So how does this sound?
Scott
Regards,
Thomas Hallgren
Scott Lewis wrote:
Hi Thomas,
Thomas Hallgren wrote:
Hi,
I'm having some trouble understanding how to propagate exceptions 
during file transfer.
I have a IFileTransferListener implementation that listens to 
IIncomingFileTransferReceiveStartEvent. When encountered, it passes 
a File handle to my desired destination using the receive() method. 
This receive method in turn is declared with a throws IOException 
clause. My handleTransferEvent is not allowed to throw any exception 
at all.
Unless I want to handle the exception right there and then, my only 
option is to throw a RuntimeException. The exception can later be 
accessed from my IFileTransfer which is what I want, but why force 
the use of a RuntimeException?
The intention was to encourage/force the handling of the exception 
there (in handleTransferEvent).  The main reason is that since the 
job is actually created by the file transfer instance, and 
handleTransferEvent is called by that job/thread, there really isn't 
anywhere else on the stack to propagate the exception *to*. Since 
there is no client controlled calling thread that is waiting on file 
transfer completion to handle the exception higher up the stack, the 
implementation of handleTransferEvent is the last place in the stack 
for the exception to be handled by the application.
I think that a more flexible approach would be to let the 
handleTransferEvent throw a CoreException and an IOException (since 
those two would cover most needs). An alternative would be to allow 
the InvocationTargetException but if that is used the 
IFileTransfer.getException() must be changed to return a Throwable.
I'm overstating the above paragraph a *little* bit.  What I mean by 
this is that we *could* add throwing CoreException (and/or 
IOException) to the handleTransferEvent, and the job that calls this 
method (defined in AbstractRetrieveFileTransfer) could catch this 
exception, simply log it, and then return a status of IStatus.ERROR 
for the job created.  But that wouldn't do too much good for user 
interface code...which wouldn't then have any chance to do anything 
in response such exceptions.  That's really the reason why I wanted 
to force the handleTransferEvent implementer to handle any 
exceptions...rather than just passing it on assuming that someone 
else (ui code higher up the stack) would handle it...because in the 
asynchronous case there is not necessarily any other code to handle 
the exception higher up on the stack.
Thanks,
Scott
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev