static void Append(Socket sock, string root) { var name = sock.Recv(Encoding.UTF8); var fileName = Path.GetFileName(name) ?? ""; var combine = Path.Combine(root, fileName); var s = new FileTapeStream(combine); Console.WriteLine("Append {0}", fileName); long result = 0; while (true) { var verDat = sock.Recv(); if ((null == verDat) || (verDat.Length == 0)) break; var version = BitConverter.ToInt64(verDat, 0); var data = sock.Recv(); var cond = TapeAppendCondition.VersionIs(version); result = s.TryAppend(data, cond); if (result != 0) Console.WriteLine(" " + result); } s.UpdateCounter(result); sock.Send(BitConverter.GetBytes(result)); }
static bool SyncChanges(RemoteTapeStream remote, FileTapeStream source, long knownVersion, string name) { try { // remote ver var rVer = remote.GetVersion(name); if (rVer == -1) { Console.WriteLine("Server unavailable: {0}", remote.Address); return false; } if (rVer >= knownVersion) { Console.WriteLine("We are up to date"); return true; } while (rVer < knownVersion) { var diff = knownVersion - rVer; var change = Math.Min(1000, diff); Console.WriteLine("Update {0} from {1} to {2}", remote.Address, rVer, rVer + change); var difference = source.ReadRecords(rVer, (int) change); // send data in groups var result = remote.Append(name, difference); if (result == -1) { Console.WriteLine("Server went offline"); return false; } rVer += change; } Console.WriteLine("Server updates sent"); return true; } catch (Exception ex) { Console.WriteLine(ex); return false; } }
// active replicator static void Main(string[] args) { if (args.Length == 0) { var fp = Assembly.GetEntryAssembly().Location + ".txt"; if (File.Exists(fp)) { args = File.ReadAllText(fp).Split('|'); } } if (args.Length < 3) { Console.WriteLine("Usage: {file} {name} {target1} {target2} etc"); Environment.Exit(1); } var file = Path.GetFullPath(args[0]); var name = args[1]; using (var ctx = new Context()) { var remotes = args.Skip(2).Select(s => new RemoteTapeStream(ctx, s)).ToArray(); var path = Path.GetDirectoryName(file) ?? ""; var e = new ManualResetEventSlim(true); using (var w = new FileSystemWatcher(path, Path.GetFileName(file + ".ver") ?? "")) { var stream = new FileTapeStream(file); w.Changed += (sender, eventArgs) => { if (eventArgs.ChangeType == WatcherChangeTypes.Changed) { e.Set(); } }; w.EnableRaisingEvents = true; while (true) { e.Wait(); bool allSynced = true; var knownVersion = GetKnownVersion(file); foreach (var remote in remotes) { var result = SyncChanges(remote, stream, knownVersion, name); if (!result) allSynced = false; } if (allSynced && knownVersion == GetKnownVersion(file)) { e.Reset(); } } } } }
static void Version(Socket sock, string root) { var name = sock.Recv(Encoding.UTF8); var fileName = Path.GetFileName(name) ?? ""; var combine = Path.Combine(root, fileName); if (!File.Exists(combine)) { sock.Send(BitConverter.GetBytes(0L)); } else { var s = new FileTapeStream(combine); sock.Send(BitConverter.GetBytes(s.GetCurrentVersion())); } }