drapostolos / rdp4j

Remote Directory Poller for Java
MIT License
46 stars 25 forks source link

Is it possible to discard poll cycle from the level of listener? #22

Open arn-cpu opened 4 years ago

arn-cpu commented 4 years ago

Hello, I am using the library to poll FTP server. After being notificated about changes by the poller, I need to retrieve file content to the application, so I do this from the lever of Listener class. However, during the try retrieving in Listener class, it may happen that file on server was locked by another process so I can't get file content and for this file and I would try in the next poll cycle. So I want map holder not to hold information about this specific file or deny changes for all files. Is there any way to do this in the latest version of library?

drapostolos commented 4 years ago

Hi

No, I can't think of any way of doing that currently. But should be possible to implement such feature.

How would you like such feature to look like? How to tell the DirectoryPoller to skip next cycle?

/Alex

arn-cpu commented 4 years ago

Hi! Actually, I would see it like this: if listener throws any kind of exception on event, then notifier will get information about it. Notifier has a reference to event, so also to the poller. Poller will know from event->FileElement which change should be discarded, so it won't be updated on poller's map. Let's say creating event should end with notifing and adding it map of successful events or something, however unsuccessful notification resulting in getting exception(specified one) will result in not adding to map or removing from it. Then based on this map of event/changes, the poller's map of files should be updated. This is kind of general idea, it can be done in different way. What do you think?

drapostolos commented 4 years ago

I'm sorry for the late reply!

I've been thinking about this for a while and you are able to do something like below with current version of the library: If your download fails, save that FileElement into a list, then in beforePollingCycle (which will fire in next poll cycle) you could try download anything in that list again.

Example:

import java.util.List;
import com.github.drapostolos.rdp4j.AbstractRdp4jListener;
import com.github.drapostolos.rdp4j.BeforePollingCycleEvent;
import com.github.drapostolos.rdp4j.FileModifiedEvent;
import com.github.drapostolos.rdp4j.spi.FileElement;

public class Demo extends AbstractRdp4jListener{
    private List<FileElement> tryDownloadAgain;

    @Override
    public void beforePollingCycle(BeforePollingCycleEvent event) throws InterruptedException {
        // Retry downloading 
        for (FileElement fileElement : tryDownloadAgain) {
            try {
                tryDownloadFile(fileElement);
                tryDownloadAgain.remove(fileElement);
            } catch (RuntimeException e) {
                // leave fileElement in list and try again next poll cycle
            }
        }
    }

    @Override
    public void fileModified(FileModifiedEvent event) throws InterruptedException {
        try {
            tryDownloadFile(event.getFileElement());
        } catch (RuntimeException e) { 
            tryDownloadAgain.add(event.getFileElement());
        }
    }

    private void tryDownloadFile(FileElement fileElement) {
        // either download file successfully, or throw on failure
    }
}