CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 673
Description
Computer OS: Debian based docker image. (buster-slim version)
FluentFTP Version: 33.0.3
Hi,
We have deployed a service in NetCore 3.1.407 that sends files to different outputs (Azure Storage, SFTP, FTPS, Sharepoint Online, etc.). In case the selected output is FTPS we are using a FluentFTP client. This service is deployed in an AKS cluster, inside a Debian docker image.
When the service is sending small files (~10kb) to an ouput that is not Ftps the RAM is around 200MB more or less, but when it is sending the same file to a Ftps output the RAM increases to 800MB/900MB and it is increased slowly in the next iterations until the pod restarts because of an Out Of Memory.
This behaviour is not reproduced when we run the service inside Visual Studio in our personal machines. The RAM increase up to ~220MB and then the garbage collector decrease the consumed RAM.
Logs :
We don't have exceptions. All the files are sent properly to the Ftps server until the pod restarts because of the out of memory.
Code:
public async Task SendFileAsync(
int executionId,
File file,
SecurityObjectUserPassword securityObject,
string certificateFingerprint)
{
var decryptedPassword = _encryptor.Decrypt(securityObject.Password);
using var ftpsClient = new FtpClient(
securityObject.Endpoint.Host,
securityObject.Endpoint.Port,
securityObject.User,
decryptedPassword);
await ConfigureAndConnectFtpClientAsync(ftpsClient, securityObject, certificateFingerprint);
await ChangeWorkingDirectoryAsync(ftpsClient, securityObject);
await UploadFileAsync(ftpsClient, file, executionId);
}
private async Task ConfigureAndConnectFtpClientAsync(
FtpClient ftpsClient,
SecurityObjectUserPassword securityObject,
string certificateFingerprint)
{
var timeoutInMilliseconds = _timeoutsOptions.FtpsConnectTimeoutInSeconds * 1000;
ftpsClient.OnLogEvent = OnLogEvent;
ftpsClient.EncryptionMode = FtpEncryptionMode.Explicit;
ftpsClient.SslProtocols = SslProtocols.Tls12;
ftpsClient.ValidateCertificate += new FtpSslValidation((ftpClient, e) => OnValidateCertificate(e, certificateFingerprint));
ftpsClient.ConnectTimeout = timeoutInMilliseconds;
ftpsClient.ReadTimeout = timeoutInMilliseconds;
ftpsClient.DataConnectionConnectTimeout = timeoutInMilliseconds;
ftpsClient.DataConnectionReadTimeout = timeoutInMilliseconds;
_logger.LogInformation("Connecting to Ftps {connection} with user {user}", securityObject.Endpoint.OriginalString, securityObject.User);
await ftpsClient.ConnectAsync();
_logger.LogInformation("Connected");
}
private async Task ChangeWorkingDirectoryAsync(FtpClient ftpsClient, SecurityObjectUserPassword securityObject)
{
var workingDirectory = securityObject.Endpoint.AbsolutePath.TrimStart('/');
if (!string.IsNullOrWhiteSpace(workingDirectory))
{
_logger.LogInformation("Changing directory from uri '{uri}' to '{workingDirectory}'",
securityObject.Endpoint.AbsolutePath,
workingDirectory);
await ftpsClient.SetWorkingDirectoryAsync(workingDirectory);
}
}
private async Task UploadFileAsync(FtpClient ftpsClient, File file, int executionId)
{
_logger.LogInformation("Uploading file {fileName}", file.FinalName);
var blobStream = await _blobStorageClient.GetBlobStreamAsync(file.InternalName);
var uploadResult = await ftpsClient.UploadAsync(
fileStream: blobStream,
remotePath: file.FinalName,
existsMode: FtpRemoteExists.Overwrite,
createRemoteDir: true);
if (uploadResult != FtpStatus.Success)
{
_logger.LogWarning(
"Execution {executionId}. Error uploading file {file} with code {Code}",
executionId,
file.InternalName,
uploadResult.ToString());
throw new FtpException($"Execution {executionId}. Error uploading file {file.InternalName} with code {uploadResult}");
}
_logger.LogInformation("File {fileName} uploaded", file.FinalName);
}