Scenario:
I have a client & server architecture. Client program captures multiple displays connected to a machine and saves as jpg file in a folder. The minimum speed is 5 images per second per display. Same folder is shared over network.
I have a windows service running on a server grade machine which pulls all the files as soon as it is created in the shared folder. These files are rendered in a browser through asp.net page through an img tag like live streaming. These files are also used to make a video later.
Problem:
Once in 8-10 days I see a slow down of file copy process where the client machine stacks more than 30,000 images in the folder but server could not pull it for some reason.
With the help of Red-Gate profiler I could find that only file copy process was stuck and could not move the file. After some time server pull process covered all the lag & came on track. To access file I am using Fast Directory Enumerator. More info here http://www.codeproject.com/Articles/38959/A-Faster-Directory-Enumerator
Initially we tried push implementation where client was pushing the images to server folder but got similar performance issue more frequently.
I confirmed that there was no network connectivity issue as well as CPU utilization was low when the process lagged. I have also handled case where a file is being accessed by another process due to which it could not be moved.
What could be the reason for this delay?
Is there any other best option to move the files to server?
Related
Short Version
Is there a more efficient or less-resource-intensive way in C# to create a zip file of a folder recursively than using System.IO.Compression.ZipFile.CreateFromDirectory?
Long Version
I have a REST API running in an Azure App Service (Scaled at P2V2 420 total ACU and 7 GB memory). One of my endpoints accepts a POST request and generates a zip file using the following code. It then returns the name of the zip file that was generated wrapped in a standard JSON format.
System.IO.Compression.ZipFile.CreateFromDirectory(sourcePath, outputPath);
This runs fine on my local machine, but appears to have scaling issues on the cloud server. When I scale up to the next level app service (P3V2 820 ACU, 14GB memory) it runs fine, but without scaling up the API returns a 503 Service Unavailable message. I am not sure which resource is constrained (cpu, memory, disk, etc.), but I don't think it's a server timeout issue since it only runs about 10-20 seconds. The zip file generated is roughly 400 files or 200MB compressed.
My question is, since scaling up costs an extra $120 per month, is there a way to generate a zip file more efficiently so I don't need to scale up the server? Would it help at all to split the zip file creation into creating and adding files steps, using multiple commands rather than using CreateFromDirectory(...)?
Other info:
This endpoint is not being hit by anyone but me
I can try to create multiple smaller zip files to see if this helps with resource consumption, but this is not ideal for my use case.
This is not the only thing running on this server which is why it's already scaled up so much
Just to clarify, the zip file does actually get created on the server and I am able to see a log entry that gets logged just before response goes back to the user, and I can see the zip file in kudu. But Azure intercepts the 200 API response for some reason and sends a 503 instead.
I have very simple code that download files from a web server and here is the code. As i said it is very basic
// use the web client to download
using (var client = new WebClient())
{
// download locally
client.DownloadFile(from, to);
}
But for some client the file does not download completely and does not throw exception. All these client come from different location and all have the same behavior that the WebClient download exactly 10 mb of ANY file above 10mb. A 8mb file is 8mb, a 20mb file is 10mb a 34 mb file is 10mb. The funny thing is we ask those user to stop using the software.
This issue is not related to the computer as we have alot of those user on laptop that the download works fine from home and it doesn't when they are at work and some it's totally reverse, the download doesn't work at work but it does at work. The behavior is also different for client within the same physical office.
We have tried to talk to their IT and they have no problem going on our http browsable directory and downloading many files over 10mb and it works perfectly and they state they never had such issue. The issue seems to spread more and more and since last windows 10 update much more client started to have this issue.
As a side note this download code has been unchanged and running for 5 years with nearly no issues.
Does anyone know why download would complete without any error (in try..catch) without having downloaded the whole file ? and Why would all these different client with the issue would be cut at EXACTLY 10,000 bytes.
Wanted to add that we tried to reinstall .NET Framework for these user in the past without any result thinking it must be an issue with that
I just edited to add this little extra details that the files they are trying to download are on an anonymous access folder so no login required and it is browsable. All user with the issue can use Chrome and Edge to navigate to the folder and right-click and download and the file is complete that way. Only .NET cannot download files above 10mb on their PC.
When i try to publish the .net core app Dlls using ftp via filezilla tool it shows an error message that the file is in use by another process.
It's understandable that the above message shows because the the file is used by dotnet.exe which is a separate process.
To overcome the issue i have to stop the application in iis each time then upload the dlls and then restart it. Due to which a very small down time is experienced , the asp.net identity session expires and it needs rdp to the server each time upload is needed.
It's also not smooth experience in comparison to asp.net mvc where we could publish the files directly without need to RPD or do some manual action.
Any work around or solution to overcome to the above issues will be appreciated.
Got the solution.
It can be done via the app_offline.html file.
You have to move the app_offline.html file to application root folder to stop/make offline the application.
Then you can push your changes and remove the app_offline.html file from application root folder.
Note:
You can put some informative message in the app_offline.html file which will be shown to user that maintenance is on progress.
Well, if you had two servers behind a load balancer, you could do (simplified):
Remove server 1 from LB
Stop app on server 1
Update server 1
Add server 1 back to the LB
Repeat 1-4 for server 2
This is called a rolling upgrade.
I have an ELB application that we have just added photo upload functionality to. Currently this saves the images in a folder within the deployment directory in ELB, saving the URL to a DynamoDb table. Everything works fine. Whenever a user wants to see an image we simply attach the URL to the src attribute of an tag in the UI and the browser downloads the image directly.
However it occurred to me that if the underlying EC2 instance is terminated and re-started we will most likely lose all the photos. Am I correct in this assumption? If so, what's the best practice here? Should uploads always be saved in an S3 bucket? Any guidance hugely appreciated.
Should uploads always be saved in an S3 bucket?
TL;DR
In an elastic cloud environment, yes always move your static content to reliable external storage (in this case S3). It will make your app scale better. See the S3 question here
Resources:
IAM Credentials Giving your app keys to access s3 right out of the box in Beanstalk.
S3 Getting Started
Media Reference Architecture Describes at least part of what you're looking for. Look at the S3/Datastore/Web Server interaction there. More here.
Longer Description
In a traditional architecture you might have a drive attached to a web server or two and you store the files there. You always expect those to be up. If you run out of disk space you have a problem. If you're server craps out, you've also got a problem. Even if you have a backup, you run the risk of both going down and you needing to restore all your data AND bringing up a server manually.
In a cloud architecture you're basically admitting that the "machine" is fallible and no longer relying on it to store any application state. It should be used to store things you need on disk to launch the app and/or temporary storage, but if you need something long term thats why services like S3 exist! By eliminating state from your app servers you can scale them automatically (however you see fit) without worrying about your users' content. If you had other services that needed that content, they could get it from there as well with the proper permissions.
In my application, I am fetching the data from my server and showing
that data in windows explorer. The data is in the form of files and
folders. You can imagine like a mapped drive on my machine which has the
data on server, I can explore this data through windows explorer.
The problem with my application is that every time I open or close the folder it fetches the data from server. It's a
redundant call and raising performance issue as data size may grow to GB's.
What I am thinking is to cache that data on my machine, and it should work in sync with data on server.
How should I implement this? Can I use any light weight database as Cache on my machine? Or there is any other way to do this.