public void LockFileConcurrentTest() { FileSystemHelpers.Instance = new FileSystem(); // Mock var file = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); var lockFile = new LockFile(file, NullTracerFactory.Instance); int count = 10; int threads = 2; int totals = 0; // Test var result = Parallel.For(0, threads, i => { for (int j = 0; j < count; ++j) { lockFile.LockOperation(() => { // simulate get/set int val = totals; Thread.Sleep(0); totals = val + 1; }, TimeSpan.FromSeconds(60)); } }); // Assert Assert.True(result.IsCompleted); Assert.Equal(count * threads, totals); FileSystemHelpers.DeleteFileSafe(file); }
public void LockFileConcurrentTest() { // Mock var file = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); var lockFile = new LockFile(file, NullTracerFactory.Instance); int count = 10; int threads = 2; int totals = 0; // Test var result = Parallel.For(0, threads, i => { for (int j = 0; j < count; ++j) { lockFile.LockOperation(() => { // simulate get/set int val = totals; Thread.Sleep(0); totals = val + 1; using (var reader = new StreamReader(FileSystemHelpers.OpenFile(file, FileMode.Open, FileAccess.Read, FileShare.Write))) { Assert.Contains(" Kudu.Core.Test.LockFileTests", reader.ReadToEnd()); } }, "operationName", TimeSpan.FromSeconds(60)); } }); // Assert Assert.True(result.IsCompleted); Assert.Equal(count * threads, totals); FileSystemHelpers.DeleteFileSafe(file); }
public void Save(JObject json) { _lock.LockOperation(() => { if (!FileSystemHelpers.FileExists(_path)) { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(_path)); } // opens file for FileAccess.Write but does allow other dirty read (FileShare.Read). // it is the most optimal where write is infrequent and dirty read is acceptable. using (var writer = new JsonTextWriter(new StreamWriter(FileSystemHelpers.OpenFile(_path, FileMode.Create, FileAccess.Write, FileShare.Read)))) { // prefer indented-readable format writer.Formatting = Formatting.Indented; json.WriteTo(writer); } }, "Updating setting", _timeout); }
private static int Main(string[] args) { // Turn flag on in app.config to wait for debugger on launch if (ConfigurationManager.AppSettings["WaitForDebuggerOnStart"] == "true") { while (!Debugger.IsAttached) { System.Threading.Thread.Sleep(100); } } if (System.Environment.GetEnvironmentVariable(SettingsKeys.DisableDeploymentOnPush) == "1") { return(0); } if (args.Length < 2) { System.Console.WriteLine("Usage: kudu.exe appRoot wapTargets [deployer]"); return(1); } // The post receive hook launches the exe from sh and interprets newline differently. // This fixes very wacky issues with how the output shows up in the console on push System.Console.Error.NewLine = "\n"; System.Console.Out.NewLine = "\n"; string appRoot = args[0]; string wapTargets = args[1]; string deployer = args.Length == 2 ? null : args[2]; string requestId = System.Environment.GetEnvironmentVariable(Constants.RequestIdHeader); IEnvironment env = GetEnvironment(appRoot, requestId); ISettings settings = new XmlSettings.Settings(GetSettingsPath(env)); IDeploymentSettingsManager settingsManager = new DeploymentSettingsManager(settings); // Setup the trace TraceLevel level = settingsManager.GetTraceLevel(); ITracer tracer = GetTracer(env, level); ITraceFactory traceFactory = new TracerFactory(() => tracer); // Calculate the lock path string lockPath = Path.Combine(env.SiteRootPath, Constants.LockPath); string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile); IOperationLock deploymentLock = new LockFile(deploymentLockPath, traceFactory); if (deploymentLock.IsHeld) { return(PerformDeploy(appRoot, wapTargets, deployer, lockPath, env, settingsManager, level, tracer, traceFactory, deploymentLock)); } // Cross child process lock is not working on linux via mono. // When we reach here, deployment lock must be HELD! To solve above issue, we lock again before continue. try { return(deploymentLock.LockOperation(() => { return PerformDeploy(appRoot, wapTargets, deployer, lockPath, env, settingsManager, level, tracer, traceFactory, deploymentLock); }, "Performing deployment", TimeSpan.Zero)); } catch (LockOperationException) { return(-1); } }