react-dev-inspector icon indicating copy to clipboard operation
react-dev-inspector copied to clipboard

在cursor中点击组件,会使用vscode打开源代码🤔

Open pangxzi opened this issue 1 year ago • 1 comments

pangxzi avatar Sep 18 '24 01:09 pangxzi

Maybe I'm too stoopid, but

are we talking about monitoring for local folder changes triggering an event

or

are we talking about monitoring (either with a permanent connection or regular repeated connections) remote folder changes triggering an event

???

FanDjango avatar Oct 05 '24 11:10 FanDjango

I like @robinrodricks idea of having a wrapper class FtpFolderMonitor that would allow monitoring a specific folder!

Would it be possible to pub/sub on FtpFolderMonitor?

markat1 avatar Oct 05 '24 12:10 markat1

are we talking about monitoring (either with a permanent connection or regular repeated connections) remote folder changes triggering an event

@FanDjango monitoring of a remote folder.

Would it be possible to pub/sub on FtpFolderMonitor?

how would pub/sub be implemented?

robinrodricks avatar Oct 07 '24 12:10 robinrodricks

monitoring of a remote folder

So you would propose to do a MLST, LIST or NLST regularly? And compare the contents?

PollInterval - how often to check the folder - default : 1 sec

You will be kicked from the server. Either because you don't ever transfer a file and time out (some servers enforce this), or if you try to circumvent this by QUIT and reconnect, you will be noticed and banned.

In any case you are severely misusing the FTP server, you might get away with it if you reduce the timing to, say every 5 minutes.

Unless of course it is your own server, then you are free to do this.

Otherwise, this is a job for NFS, RSYNC or other stuff higher up the tree.

how would pub/sub be implemented?

I don't even know what that is. Enlighten me, please, someone.

FanDjango avatar Oct 07 '24 16:10 FanDjango

So you would propose to do a MLST, LIST or NLST regularly? And compare the contents?

Yes.

You will be kicked from the server.

Then we can keep the default to 10 seconds or 60 secs.

Unless of course it is your own server

Yes this would be the most common use case. Or even if its a web host, they should allow polling every 1 min.

I don't even know that that is. Enlighten me, please, someone.

Its normally used on the cloud. I'm not sure why the user is asking us to implement it at the library level.

https://aws.amazon.com/what-is/pub-sub-messaging/

robinrodricks avatar Oct 08 '24 06:10 robinrodricks

Reason I ask for pub/sub is some sort of control of broadcasting certain events to specific subscribers. It was just the architecture that came to mind.

Anyway, I guess pub/sub doesn't have to be part of this solution - it could be integrated seperately, which problably makes more sense.

markat1 avatar Oct 09 '24 04:10 markat1

Reason I ask for pub/sub is some sort of control of broadcasting certain events to specific subscribers

You can surely handle that as part of your user code.

robinrodricks avatar Oct 09 '24 06:10 robinrodricks

@markat1 I have committed the first version of these classes. Can you download the FluentFTP project, build from source and try using it?

New classes:

  • AsyncFtpFolderMonitor - async version
  • FtpFolderMonitor - sync version

Usage:

var client = new FtpClient(...);
var monitor = new FtpFolderMonitor(client, "/remote/folder");

// optional config
monitor.WaitTillFileFullyUploaded = false;
monitor.Recursive = false;
monitor.PollInterval = 60;

// add events
monitor.FilesAdded += your_event;
monitor.FilesDeleted += your_event;
monitor.FilesChanged += your_event;
monitor.Start();

Since I'm very busy I am hoping you can fix minor bugs and submit a PR with a working version. I don't have time to test it on my end right now.

I have used System.Threading.Timer. I am not sure if it works in all use cases. Please change this to whatever timer is best suited to such projects.

File change detection is done by filesize. I suppose an alternate way would be using the date modified.

robinrodricks avatar Oct 09 '24 11:10 robinrodricks

I testet following in a console program - I have replaced connection information in the examples shown here.

both Sync and async version - doesn't respond back on filesAdded, FilesDeleted or FilesdDeleted unfortunately

using FluentFTP;
using FluentFTP.Monitors;

var client = new FtpClient("Server", "User", "Password");

client.Connect();

Console.WriteLine("Running FtpFolderMonitor");

var monitor = new FtpFolderMonitor(client, "OutboxDirectory");

monitor.WaitTillFileFullyUploaded = false;
monitor.Recursive = false;
monitor.PollInterval = 5;

monitor.FilesAdded += Monitor_FilesAdded;
monitor.FilesChanged += Monitor_FilesChanged;
monitor.FilesDeleted += Monitor_FilesDeleted;

void Monitor_FilesAdded(object? sender, List<string> e) {
	Console.WriteLine("File added");
}

void Monitor_FilesChanged(object? sender, List<string> e) {
	Console.WriteLine("File changed");
}
void Monitor_FilesDeleted(object? sender, List<string> e) {
	Console.WriteLine("File removed");
}

Console.ReadLine();

using FluentFTP;
using FluentFTP.Monitors;


var asyncclient = new AsyncFtpClient("Server", "User", "Password");

client.Connect();

Console.WriteLine("Running FtpFolderMonitor");

var monitor = new AsyncFtpFolderMonitor(asyncclient,"OutboxDirectory");

monitor.WaitTillFileFullyUploaded = false;
monitor.Recursive = false;
monitor.PollInterval = 5;

monitor.FilesAdded += Monitor_FilesAdded;
monitor.FilesChanged += Monitor_FilesChanged;
monitor.FilesDeleted += Monitor_FilesDeleted;

void Monitor_FilesAdded(object? sender, List<string> e) {
	Console.WriteLine("File added");
}

void Monitor_FilesChanged(object? sender, List<string> e) {
	Console.WriteLine("File changed");
}
void Monitor_FilesDeleted(object? sender, List<string> e) {
	Console.WriteLine("File removed");
}

Console.ReadLine();

markat1 avatar Oct 10 '24 07:10 markat1

You have missed to start the monitor.

monitor.Start();

Just test one version (sync is fine).

The class is easy to understand. You can add breakpoints into the PollFolder method and see what's going on.

Since I'm very busy I am hoping you can fix minor bugs and submit a PR with a working version. I don't have time to test it on my end right now.

robinrodricks avatar Oct 10 '24 11:10 robinrodricks

I played around with it for a couple of hours - does work fine - maybe a small change would be to put restart time in the try catch finally - just to make sure it's always running

/// <summary>
/// Polls the FTP folder for changes
/// </summary>
private async void PollFolder(object state) {
	try {

		// exit if not connected
		if (!_ftpClient.IsConnected) {
			return;
		}

		// stop the timer
		StopTimer();

		// Step 1: Get the current listing
		var currentListing = await GetCurrentListing();

		// Step 2: Handle unstable files if WaitTillFileFullyUploaded is true
		if (WaitTillFileFullyUploaded) {
			currentListing = HandleUnstableFiles(currentListing);
		}

		// Step 3: Compare current listing to last listing
		var filesAdded = new List<string>();
		var filesChanged = new List<string>();
		var filesDeleted = new List<string>();

		foreach (var file in currentListing) {
			if (!_lastListing.TryGetValue(file.Key, out long lastSize)) {
				filesAdded.Add(file.Key);
			}
			else if (lastSize != file.Value) {
				filesChanged.Add(file.Key);
			}
		}

		filesDeleted = _lastListing.Keys.Except(currentListing.Keys).ToList();

		// Trigger events
		if (filesAdded.Count > 0) FilesAdded?.Invoke(this, filesAdded);
		if (filesChanged.Count > 0) FilesChanged?.Invoke(this, filesChanged);
		if (filesDeleted.Count > 0) FilesDeleted?.Invoke(this, filesDeleted);

		if (filesAdded.Count > 0 || filesChanged.Count > 0 || filesDeleted.Count > 0) {
			ChangeDetected?.Invoke(this, EventArgs.Empty);
		}

		// Step 4: Update last listing
		_lastListing = currentListing;
	}
	catch (Exception ex) {
		// Log the exception or handle it as needed
		Console.WriteLine($"Error polling FTP folder: {ex.Message}");
	}
	finally {
		// restart the timer
		StartTimer(PollFolder);
	}
	                  
	
}

markat1 avatar Oct 16 '24 16:10 markat1

Why don't you create a PR from this, then it can be an official change? I'll merge it then.

FanDjango avatar Oct 17 '24 17:10 FanDjango

hmm don't think I'm allowed to make a pull request - anyway it's just a small change :)

markat1 avatar Oct 21 '24 16:10 markat1

Never mind, I'll take care of it...

FanDjango avatar Oct 21 '24 17:10 FanDjango

I merged it.

FanDjango avatar Oct 22 '24 18:10 FanDjango

FTP monitors are released.

https://www.nuget.org/packages/FluentFTP/52.0.0

robinrodricks avatar Nov 30 '24 08:11 robinrodricks