views:

121

answers:

5

I need to independently record events on different computers and reconstruct which order those events happened relative to each other. The solution calls for each computer to be relatively independent; they cannot directly talk to each other or a single source.

My initial solution recorded the time on each machine, but since times can be different on different machines, and can change throughout the day, this did not completely solve my problem. I decided to share with all machines whenever a machine (1) starts the process, or (2) has its system clock change.

So from each machine I get a log full of these

public class Activity {
    DateTime TimeOccurred { get; set; }
    string Description { get; set; }
}

Whenever (1) or (2) happens above, I add an activity to the log and broadcast it to the other machines, who add the same activity to their log, with the TranslatedTime being their own time:

public class TimeSynchronization : Activity {
    string SourceMachine { get; set; }
    DateTime TranslatedTime { get; set; }
}

So machine A would have (in order):

TimeSynchronization "started" at 3:00 am.
Activity "asked a question" at 3:05 am.
TimeSynchronization from machine B at 3:05 am.
TimeSynchronization "clock changed" at 3:03 am.
Activity "received an answer" at 3:04 am.

And machine B would have (in order):

TimeSynchronization "started" at 3:05 am.
TimeSynchronization "clock changed" at 3:06

So I need to reconstruct the same order and timing of these above events, to something like:

On machine A: TimeSynchronization "started" at 0:00
On machine A: Activity "asked a question" at 0:05
On machine B: TimeSynchronization "started" at 0:05
On machine A: TimeSychronization from machine B at 0:05
On machine A: TimeSynchronization "clock changed" at 0:06
On machine B: TimeSynchronization "clock changed" at 0:06
On machine A: Activity "received an answer" at 0:07

What is the best way to take a List<Activity> from each machine and merge it into one list with the events in order?

+1  A: 

Looks like they want you to intuit towards distributed transactions

Also, check out Network Time Protocol:

NTP is a protocol designed to synchronize the clocks of computers over a network.

karim79
+2  A: 

If the two machines are connected via the network your program can ask the other machine what time it is. That way your program on machine A could ask for the time on both A and B and then log both times.

You mention that the time could change during the day (presumably the user changed the time). You can detect this by using the Win32.TimeChanged event.

JonnyBoats
Yes, the problem statement above includes time changes and machines talking to each other. I'm struggling with the "merge it all together in the correct order" part.
Michael Hedgpeth
Pick one of the computers A _or_ B, and always log the time from that computer.
JonnyBoats
That works if the computer never goes back in time. See the example above. The "received an answer" activity needs to be *after* "asked a question" even though on its own machine it was before it on the time marked.
Michael Hedgpeth
+2  A: 

Atomic time, and a webservice that would give it to you. That's what you need. Realistic? No idea. But at least you wouldn't need to worry about the n computers trying to sync their clocks.

Jagd
A: 

First up: if the operations on each machine are genuinely parallel, you cannot guarantee that there is a single canonical serialized ordering. If there is some coordination in the overall process, you'd be better off using some kind of sequencing in the protocol, so that you can just sort by it.

Apart from that, you need to calculate clock skew between machines in order to adjust times. The way you do that is reasonably simple: ask the other machine for its current time, and measure the round-trip time for that request. Assume that the time reported by the remote machine was true at half the round-trip time ago (this assumes symmetric delays on average - not always true, but you can't really do better without digging deep into the network layout), and subtract it from the current machine's time. That's your clock skew. You may want to measure the skew several times and take an average, to even out intermittent lag on the connection.

Barry Kelly
+1  A: 

I think you want to record everything in UTC (universal time). This is will allow for times to be recorded with their times relative to a common point in time and makes comparing dates/times very easy. to display them in local time you simply identify the offset and and compute the difference from UTC time to local. e.g. on the east coast its UTC -5, so if the UTC time is 17:00, the local time in New York is 12:00 and in Dallas its UTC-6, so its 11:00am.

so if you have an event at 11:10 am in Dallas its UTC time is 17:10, and an event in New York at 12:05 pm is 17:05 UTC, you know that the New York event occurred first, but if you raw compared the times this wouldnt appear to be so.

UTC also has the advantage that it always represents all 24hrs in the day, so that in the fall when you go off day light savings time, you dont get 2 sets of 2am-3am events and you dont lose hours when you spring forward to go onto dalylight savings time.

MikeJ