Start a program (c# and mysql Database) simultaneous on several computers - c#

I have to start a program on several computers at the same time (within ms).
The program read out of and write into a mysql database. To ensure the simultaneous start, I thought about the sql dependency but does it also work for mysql? Are there any other ways to guarantee the synchronous start?
It´s a project inside a laboratory. So it´s just a small network.
Greetz

Synchronyze Operating System clocks with and NTP and schedule the start (once loaded) to ensure real-time synchrony.
Run your program with a clocktime to start, and put some trigger to do it.
I'm working for years in distributed systems and is the most common solution.
Accuracy on todays clocks starts on nanosecs (10^-6 secs) and there's high accuracy clocks (10^-7 till 10^-8 secs)
You can read a discussion about clocks here and Time synchronization vs alternatives here

Related

What causes the slow down in crawling from a laptop program?

I have a project that I have managed to save from a server that was outsourced and managed to get most of it working on one of the laptops I have at home. It has OS Win 8.1r, VS 2017, SQL Server Express 2017, and I wrote the DLL I use in my app in C# .NET version 4.6.1.
I am currently every night at midnight manually running some stored procs that fill some stat tables due to no MS Agent existing in SQL Server Express, then runs an index maintenance proc that either REBUILDS or DEFRAGS the indexes plus rebuilds stats before I manually restart the BOT from a command prompt at just after midnight.
However I have noticed if I leave the laptop on for 3-5 days the time each run takes to get (on average), 40 races and 5-20 runners per race going through proxies gets slower and slower. I just rebooted now as last night it took from 1am to 11am to crawl, scan with regex to get info and save to the DB races and runners.
However if I look at the CreateDate times I store on every new race I can see a pattern..
Yesterday took 10 hours to do 40 races and runners,
Saturday took 4 hours to do 50 races and runners
Friday 3 hours 49 races
Thursday 5 hours 42 races
Wednesday 5 hours 32 races
Tuesday 1 hour 36 races
Obviously over time more and more races & runners are stored in the DB, so retrieval times from indexes, storage etc gets longer but after a reboot it is quick Harry, I just restarted it tonight, rebuild the indexes then let it go and its already done 7 races in 7 minutes.
Obviously I haven't got a server to put this on, the last attempt resulted in an old boss putting it on a French server that doesn't allow access to online betting sites and my BOT uses the Betfair API.
It runs on my laptop ok apart from
-the speed of getting all races and runners into the DB lengthens over time. The longer I leave it on the longer it takes, despite all the clean up operations I do nightly (Delete old log messages, locks, and rebuild stat tables before a reindex/defrag job).
-For some reason the logfile I output debug messages to for after the fact debugging e.g I look for SQL Errors, Connection Errors, Proxy Issues, RegEx errors and I output this through the console app I am using the DLL with at the moment to a logfile in C:\programdata\myproj\logfile.txt - it has permissions as it writes to the file however once the job is over if I try and open it up in my standard Editor - Editplus, it just opens up a blank document. If I open it in Notepad first I can see all the debug then I can copy n paste it to a blank Editplus document.
It never did this before on my Work PC, Permissions are okay, the file is being written to and I don't get any "permission denied" or other I/O errors when opening the logfile up, it's just empty if I don't open it in Notepad.
So I'd like to know what sort of actions are happening to slow this job down over time that a reboot fixes. I know the old saying we used to get from our techies when we had a bug or issue with our PCs at work "have you tried turning it on and off again" - which does for some reason fix so many issues.
I'd just like to know what sort of issues could be happening to slow it down over days that I could maybe automate a clean up job so it doesn't happen. I used to run the exact same code on my Work PC connected remotely to a server every day for months before forced to do reboots due to Windows Updates. So it never used to do it with my bad practice at work of leaving my PC on all the time.
Is the disk getting fragmented - and why wouldn't it require a disk defrag to solve it after rebooting.
The registry? What could get worse and worse over time that a reboot fixes.
Or is it the fact I am using MS SQL Express 2017 and there is some I/O issue with the files it writes to that slows down over time.
I would just like to be able to leave my laptop on with this BOT running at specific times during the day and not worry about it taking 11 hours to complete the first import job.
It is now 37 mins past, been running for 20 mins and it has imported 15 races and runners, about a quarter of the total, so should be finished in about an hours time tonight, and I have JUST re-started my laptop, nothing else, and it has speeded it up from 10 hours yesterday night?
What could be slowing it down lover time, and can I fix it at all?

"Deterministic" or real time like application programming on .NET

I have developed a .NET program for a SCADA solution to control a heavy machine but I have some problem related with time management on the application and I am looking for some wise advisory.
I use a Winforms timer to check regularly and record the values of some variables related with the process being controlled. The application spends about 40h turned on without interruptions. At the beggining the timer does it's job, at a 5 minutes time interval, it records the values to the database. But at the end of the 40 hours, the same timer without changing it's configuration is invoked only 1 time per hour.
So my question basically is "What's the best way to ensure a certain code is run on fixed periodic intervals in a program developed in C#?" I don't really need a pure real time solution, just ensure a function is called always in fixed time intervals. But those intervals are not quite critical, we are talking about 5 minutes length. Is not important how long it takes to run the code but it is important that the code is always executed on the same period of time.
Is it better option to run the application as a service rather than a regular user-space program? Is it better option to develop in C++ the "time critical" part and communicate with the C# code via sockets or so?
At the beggining the timer does it's job, at a 5 minutes time interval...
I don't really need a pure real time solution...
Windows Task Scheduler is built for this in mind. With it you can simply have it run an .exe of your choosing with optional arguments. If the schedules are static you are arguably better off setting up the schedule in the TS UI or if complex, via the COM API.
Much better than having a another process hanging about counting down when TS already does it.

Reset clock rate with SetSystemTimeAdjustment without using time servers

Question:
On a machine that has its external clock synchronizations switched off how can I reset the clock to its normal rate? that is what should I set the timeAdjustment parameter of SetSystemTimeAdjustment function to?
Description:
My goal is to synchronize clocks across thousands of machines in such a way that clock always goes forward.
If for whatever reason a clock needs to be set back clock rate slows down.
I have made an observation that my workstation presents very different timeAdjustment values fetched with the function getSystemTimeAdjustment.
Sometimes I am getting 155854 (# of 100ns), sometimes 156002 sometimes other values.
Yes, I know it is 15.58ms versus 15.60ms but still the issue persists.
My best guess so far is that whoever is in charge of my workstation’s clock adjustments (domain controller?) sets these value according to the clock drift which in turn depend on many other physical factors.
On a machine that is not connected to domain controller and has its synchronization with Internet time servers disabled I have been observing clock drift measured in seconds per
10 minutes what after reading Jeff's article on PC clocks
makes me think that such a drift is nothing unusual at all.
If the drift was constant I could just restore the value from before I started changing clock rate (which is a good approximation), but clock drift is not constant.
Primarily coding in C#. Will accept answers in C++ too.
This blog post explain mysteries behind windows clock. At me time server start sounding good idea.
http://www.mathpirate.net/log/2010/03/20/temporal-mechanics-changing-the-speed-of-time-part-ii/

What is the most stable time stamp Source for a .NET application?

Base Issue
I am having an issue with time stamps in my C# application. I receive data from a remote TCP connection asynchronously. Every time I receive data, I update a time stamp variable to DateTime.Now. On a separate thread, once a second, I check if it has been longer than a predefined timeout period since my last receive and if so, disconnect. This method has been working for many years, but now I have a situation where the application is installed on a machine with an unstable time source. Every few days, the machine time "auto-corrects" and I drop the connection prematurely. The code is basically as follows:
Receive Process
void OnReceiveComplete(IAsyncResult ar) {
...
mySocket.EndReceive(ar);
lastRxTime = DateTime.Now;
...
}
Check Process
void CheckConnection() {
TimeSpan ts = DateTime.Now.Subtract(lastRxTime);
if(ts.TotalMilliseconds > timeout) {
Disconnect(string.Format("No packet received from the server for over {0} seconds.", timeout / 1000));
}
}
I have valid Wireshark captures during the issue and right before the disconnect I see NTP traffic that culminates in what looks like a correction of at least 1 minute. This obviously causes the check process to fail.
Technical Details/Answers to Expected Questions
I have control of both ends of the connection, but not the physical layer in between (often a low quality satellite link), This is why this timeout check is in place.
Since the data is Asynchronous, there is a provision to send out a small heartbeat if no data has been sent from the server for a period of time equal to half the timeout.
There can be multiple instances of this process (i.e. on machine connecting to multiple different servers.
All communications use Asynchronous methods (which supposedly use completion ports).
The check process is run on a separate thread that is shared by all clients on a single machine.
Completed Research (i.e. Possible Solutions)
My Google searches to this point have lead to the following:
I realize I should have used DateTime.UtcNow instead of DateTime.Now for performance reasons. This would not affect the issue itself.
An implementation depending on Ticks would be a better solution.
There are two options for getting ticks - Environment.TickCount and Stopwatch.GetTimestamp()
According to my research, Environment.TickCount may be susceptible to time adjustments, but I am not sure under what circumstances. Also, since I use this same methodology in other higher performance circumstances, the 10-16 mSec resolution may be an issue (though not in the specific case I am presenting here).
The Stopwatch.GetTimestamp() can fallback to DateTime.Now.Ticks when a High Performance clock is unavailable. I am unsure how often that will occur (do any machines NOT come with a high performance clock anymore), but I am certain that if it resorts to Ticks the same issue will occur.
I have also read that Stopwatch.GetTimestamp() will use the QueryPerformanceCounter() API call, and that can be unstable when called from multiple threads.
Ultimate Question
I am curious what the best method to generate the lastRxTime time stamp would be? Am I worrying too much about low likelihood issues in the Environment.TickCount and Stopwatch.GetTimestamp() functions? I am open to alternative implementations as long as they take the multi-threaded nature of the application as well as the link quality issues into account.
UPDATE 7/17/2013 (A solution has been deployed!)
I have deployed a solution and want to let everyone in on the details. In general, there may not be one accepted answer, but after going through this experience I can say that the original solution was definately an issue. I will try to provide as much detail as possible:
First, the NTP issue was actually a symptom of a different issue. The network exhibiting the issue is AD Domain with the two servers running my code set up as Domain Controllers. It turns out DCs are time sources for the domain. It also turns out that the system time drifts from the real time clock on these systems by up to a minute over approximately 11 days, at which point Windows is correcting the slip. Once it corrects the slip on the first DC, the second DC syncs his time and both run into the problem described above.
Based on the feedback and my original research, I created a test program to run during a disconnect to log values for DateTime.Now, Environment.TickCount, and Stopwatch.GetTimestamp(). What I found was that during the correction, neither Environment.TickCount nor StopWatch.GetTimeStamp() slipped at all, meaning they were good candidates to use as a replacement for DateTime.Now(). I went with TickCount because it is guaranteed to be on all of my deployed servers (whereas the stopwatch could fall back to the DateTime object on some machines that I have yet to find). It is working so far without issue. I did due dilligence on the roll-over issue to prevent that form being a problem, but will need to wait for my system to be up that long be sure.
I want to note that if anybody else is experiencing similar problems, they should not discount the use of any of the other presented solutions in the list below. Each has its own merrit, in fact the simple counter is likely the best solution for most circumstances. The reason I did not go to this solution was that I have similar code in separate area that depends heavily on tight timings. I cna handle the 16 mSec or so resolution of the tick count there, but cannot handle the drift of time that the counter solutions incur (I used code like that in a separate product that wound up drifting by over a second an hour and bringing me out of spec for the project).
Again, thanks to all and if any more comes up I will be sure to update the question.
I don't see any problem with using Environment.TickCount. The documentation states that it returns:
A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started.
It goes on to say:
The value of this property is derived from the system timer and is stored as a 32-bit signed integer.
I'm not seeing how NTP time correction can affect this. Do you have a link that suggests otherwise? The tricky part is dealing with the wrap-around. So, when comparing the current tick count to the previous, if you get a negative number, you'll know wrap-around occurred.
Personally, I think this is the superior mechanism to use, because the return value is in millisonds, so the conversion factor for your timeout will be straightforward. Otherwise, with Stopwatch.GetTimestamp you'll have to do some additional work to factor in the tick frequency.
Furthermore, I'm assuming this is implemented internally with a call to the Win32 GetTickCount function. (dotPeek shows that it's marked with MethodImplOptions.InternalCall, so I can't tell for sure) But the documentation for that states:
Remarks
The resolution of the GetTickCount function is limited to the
resolution of the system timer, which is typically in the range of 10
milliseconds to 16 milliseconds. The resolution of the GetTickCount
function is not affected by adjustments made by the
GetSystemTimeAdjustment function.
On second thought, since you're periodically checking only every second, the resolution of the timer only has to be < 1 sec. There is zero point in trying to do any better, so why use any API call at all?
private int m_conTimer;
void OneSecondThreadCallback() {
if (++m_conTimer >= TIMEOUT_VALUE)
// Connection timed out. React accordingly.
}
There are a few good reasons not to use DateTime.Now for this purpose
As you pointed out, there are performance issues. Mostly this is because it internally has to translate to the local time zone.
Since it is the "now" of the local time zone, it is unsuitable for comparison or calculation. This is because many time zones have discontinuities twice a year as Daylight Saving Time transitions occur. If you are comparing against your last event time, then when the clocks roll forward you would have an extra hour. When they roll back, you could be off anywhere from 0 to 60 minutes (depending on exactly when you did your comparison).
It has a much lower precision than Stopwatch or Environment.TickCount. While DateTime is capable of representing very small amounts of time, the system clock itself is only accurate to about 10 to 30 ms. (But perhaps that's not so important for your use case.)
Using DateTime.UtcNow does address the first two points, but not the third. For that, you need to stay away from DateTime completely.
Also - there is the concept of "clock drift". Clocks may slow down or speed up over extended periods. If the OS has a time synchronization source, it can actually adjust the amount of time that actually passes in a tick in order to compensate. You can read more in this article (see the "Time Adjustments" section).
You may also be interested in the ClockRes utility can be used to give you information about your system timer resolution.
HOWEVER - your use case is probably best served not by any of these techniques. You said you were interested in cancelling an event after a timeout period. You also said that you have a separate thread that checks periodically to see if the timeout period has elapsed. All of that is unnecssary. Instead, just use a Timer class.
Be careful, there are three different timers available in .Net. You probably want a System.Threading.Timer:
// start the timer, callback in 10000 milliseconds, and don't fire more than once
var timer = new Timer(TimerCallback, null, 10000, Timeout.Infinite);
// to reset the timer when you receive data
timer.Change(10000, Timeout.Infinite);
// to stop the timer completely
timer.Change(Timeout.Infinite, Timeout.Infinite);
// and in your callback
private void TimerCallback(object state)
{
// disconnect, or do whatever you want
}
If its possible you would be resetting the timer from multiple threads, then you should instead use a System.Timers.Timer - which is thread safe.
// to set up the timer
var timer = new Timer(10000) {AutoReset = false};
timer.Elapsed += TimerOnElapsed;
// to start the timer running
timer.Start();
// to reset the timer
timer.Stop();
timer.Start();
// and the callback
private void TimerOnElapsed(object sender, ElapsedEventArgs args)
{
// disconnect, or do whatever you want
}
Am I worrying too much about low likelihood issues in the Environment.TickCount and Stopwatch.GetTimestamp() functions?
Potentially, yes.
I would prefer the Stopwatch.GetTimestamp() option. This will use high performance timers if they are available on your system, and fallback to DateTime.Ticks if that isn't an option. As such, you'll get the best possible timing when available on your given hardware, and a good option as a fallback when high performance timers are not available.
While Environment.TickCount could be an interesting option, you would need to handle the case where this overflows if it's possible that your machine will be operational for more than 24.9 days.

How much time do users actively spend on my program?

One of the analytics that I had to have on my program was How much time do users spend on my program? It is basically a measure of how useful the users find my program that they actively keep on using it. and used to promote users to actively start using the application.
I initially thought of using Time Span between when they start the application to when they close it but the problem was that users could just keep the application open and not use it.
I currently use TotalProcessorTime (C#/VB .Net) to let management know how much time users actively spend on the application. TotalProcessorTime give the amount an application uses the CPU but this does not translate well to management because even when a user actively uses the application for a few minutes the TotalProcessorTime would be far less.
Any out of the box thinking / suggestions?
Since you want to know how much people use your software as opposed to how long your software uses the CPU (they aren't always the same thing), the way I'd do it (and I actually used this before) is to use GetLastInputInfo.
You can have a timer in your application and check every say.. 500ms if your application is the active application and GetLastInputInfo returns the system has been idle for less than some threshold (5-10sec depending on what your application does). As long as both of these two conditions hold, you can add 500ms to your application active usage.
Of course, you can still track total CPU usage as a separate statistic, but I think my way provides a more... focused usage counter for your application.

Categories