[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[ecf-dev] Re: eclipsefiletransfer

Hi Gerhard,

OK, I've finally had a chance to reproduced this bug and figure out what was going wrong.

There was a bug in the org.eclipse.ecf.example.collab.share.io.FileTransferSharedObject class. This bug was kind of subtle. What was happening was that when the user initiates a file send, an instance of EclipseFileTransfer was created/added to the container. EclipseFileTransfer extends FileTransferSharedObject, which extends TransactionSharedObject.

As part of the activation of FileTransferSharedObject (i.e. in the TransactionSharedObject.activate() method) the method TransactionSharedObject.addRemoteParticipants() method is called. This method is responsible for adding to the TransactionSharedObject.participantIDs the current group participants...i.e. on line 76 of TransactionSharedObject is this:

               addRemoteParticipants(getContext().getGroupMemberIDs());

This adds *all* the group members to the list of transaction participants (those that are expected to respond before the sender considers the transaction committed). But note that for the case when the user is sending the file to just a *single* recipient (i.e. via drag and drop to an entry in the buddy list), that the other participants (i.e. the second slave) should *not* be added to this list of transaction participants...because the sender will wait until it gets a response of some kind from all participants. This is what was causing your transfers to timeout when three participants were included...the master/sender was waiting for a response from the recipient that wasn't ever intended to receive the file...and it would eventually just timeout and fail.

So, the fix for this is to override the addRemoteParticipants() method in FileTransferSharedObject and define it like this:

In FileTransferSharedObject

protected void addRemoteParticipants(ID ids[])
{
if (ids != null && participantIDs != null) {
for(int i=0; i < ids.length; i++) {
if (targetReceiver == null) {
if (!getHomeContainerID().equals(ids[i])) participantIDs.addElement(ids[i]);
} else {
if (targetReceiver.equals(ids[i])) participantIDs.addElement(ids[i]);
}
}
}


   }

What this does is check to see if the *targetReceiver* is null. If it is null (which means 'send to everyone in group') it adds the participant to the participantIDs list and the sender waits for all receivers to respond before continuing with file transfer. If the targetReceiver is *not* null (which means the file is intended to be sent to a *specific* single recipient), then the ids[i] entry is only added if it matches the targetReceiver ID. The participantIDs list then only includes the targetReceiver, and so the sender just sends to that one receiver and doesn't incorrectly wait (in vain) for the others to respond.

I've checked these changes in. Unfortunately they didn't get into yesterday's 0.4.0 distribution so you will have to pick them up from CVS. We will be doing another build (0.4.1) within two weeks, and these changes will be in there.

NB: My intention is to soon define/create a 'file transfer' API plugin for ECF and rewrite/refactor *all* of this file transfer code that's in the org.eclipse.ecf.example.collab project. So all this is going away shortly to be replaced with 1) an API plugin for file transfer using ECF containers, and 2) some implementations that provide some of the same basic services but use the Eclipse extension point mechanisms and ECF extensibility API (i.e. IContainer.getAdapter()) to provider runtime access to the file transfer capabilities...hiding the specific implementation classes (like EclipseFileTransfer, FileTransferSharedObject, etc). Please let me know if you would like to help out with this...as perhaps some of the work you are doing on your system could inform this work...or you could even make a code contribution, etc and work with me/us to get this file transfer API defined and implemented within ECF.

Thanks for reporting the problems and being patient.  It's appreciated.

Scott

Gerhard Maier wrote:

Hi Scott,

my application:
1. create master

2. create slave client
3. master detects connectionevent from slave (ID)
3.1 create eclipsefiletransfer to send (only to ID; [targetID])

4. create slave2
.. (like 2+3)

in my application, which is heavily based on the collab example, on first connect a eclipsefiletransfer is created an may be done, when the second slave comes into play. But this is not depending on the sequence.


collab example: 1. variant (one application) - connect 3 clients via 3 projects - drop a file on one client in a buddy list to make transfer

2. variant (3 applications)
- each connecting to localhost via one project
- drop a file on one client in a buddy list to make transfer

here no eclipsefiletransfer exists 'til i drop a file in the buddy list and the problem is the same. I mean, i'm immediatlly getting the exception after the timeout, when i have 3 clients.


br gerhard



Scott Lewis wrote:

Hi Gerhard,

Gerhard Maier wrote:

hi Scott,

long time no 'hear'.

I've encountered a problem with the filetransfer.

I have a master client and 'slave' clients. If a the master detects a new slave client it tries to upload some required files.

Now the problem. It works just fine if i only have a single slave client connected. Do i connect another one, then i get on sender-side a 'TransactionSharedObject.waitToCommit' exception.



A question: *when* is this second slave client connected? So I understand...is the sequence:


1. Connect master client
2.  Connect slave client
3.  Create file transfer shared object
4.  Connect second slave client

or some other sequence? I think you've found a bug in the handling of these objects once an initial file transfer is complete. But I want to know the sequence here to make sure I understand what's going on.


org.eclipse.ecf.core.SharedObjectAddException: Container GUID[J4oTLqXy57B3EjZ8neDdwe5QE74-] had exception adding shared object StringID[-2855529713526529108]: org.eclipse.ecf.core.SharedObjectAddAbortException: Timeout waiting for create responses
at de.netallied.jviz.net.share.TransactionSharedObject.waitToCommit(TransactionSharedObject.java:184)


at org.eclipse.ecf.provider.generic.SOContainer.addSharedObjectAndWait(SOContainer.java:315)

at org.eclipse.ecf.provider.generic.SOManager.addSharedObject(SOManager.java:200)

at de.netallied.jviz.net.share.GenericSharedObject.makeObject(GenericSharedObject.java:492)

...


The curios thing is, i'm getting no exception or error message in the debug(..) methods on client side.



Is there a connection limit or something? (i don't think so, but who knows; i ask nevertheless)



No...but I think the master client is failing to send a request to create a shared object replica on the remote slave because it thinks it's job is done (incorrectly).


So please let me know about these sequence question and we'll debug. I suspect this will be easily fixed.

Thanks,

Scott




I've also tested it with the example/collab (checked out at 05.08.) and there it is the same. Connecting to 3 clients over resources (or making 3 eclipse applications) and try to send file to a specific client (i.e. by dropping a file on one member in the buddy list).

I also checked out current head of ecf from cvs and tested it with the collab example. Result is the same as above.


In specific:

1. receiver (FileTransferSharedObject):
- makes the output file (activated())
- calls super.activated() (TransactionSharedObject) in order to send the response and there seams nothing unusual here while debugging (0.3.3).


2. sender :
the sender seams not get a response while waiting to commit.

The created file is empty because no transfer takes place.



best regards