QueryResponses.cs, DumpIndex.cs, IQueryResult.cs, QueryExecutor.cs, QueryResult.cs...
[beagle.git] / beagled / IndexSynchronization.cs
blob593bd8dcfd054dd3ed40671abc302e825d4106c5
1 //
2 // IndexSynchronization.cs
3 //
4 // Copyright (C) 2005 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.IO;
29 using System.Collections;
30 using System.Threading;
32 using Beagle.Util;
34 namespace Beagle.Daemon {
36 public class IndexSynchronization {
38 // 1 hour synchronization period
39 static private int sync_interval_in_minutes = 60;
41 // Synchonization lock object
42 static private object synchronization_lock = new object ();
44 // Original index storage directory
45 static private string remote_index_dir = Path.Combine (PathFinder.StorageDir, "Indexes");
47 ////////////////////////////////////////////////////////////////
49 public enum SynchronizationTarget {
50 Local,
51 Remote
54 static public void Initialize ()
56 Logger.Log.Debug ("Initializing index synchronization");
58 if (! Directory.Exists (remote_index_dir))
59 Directory.CreateDirectory (remote_index_dir);
61 // Initial index synchronization
62 Synchronize (SynchronizationTarget.Local);
64 Scheduler.Task task;
66 // Add the synchronization task to the scheduler
67 task = Scheduler.TaskFromHook (new Scheduler.TaskHook (SynchronizeHook));
68 task.Tag = "Synchronize Indexes";
69 task.Priority = Scheduler.Priority.Delayed;
70 task.TriggerTime = DateTime.Now.AddMinutes (sync_interval_in_minutes);
71 task.Source = synchronization_lock;
72 Scheduler.Global.Add (task);
74 // Set up the shutdown synchronization task
75 task = Scheduler.TaskFromHook (new Scheduler.TaskHook (ShutdownHook));
76 task.Tag = "Synchronize Indexes on Shutdown";
77 task.Priority = Scheduler.Priority.Shutdown;
78 task.Source = synchronization_lock;
79 Scheduler.Global.Add (task);
82 ////////////////////////////////////////////////////////////////
84 static public void Synchronize (SynchronizationTarget target)
86 Stopwatch watch = new Stopwatch ();
87 watch.Start ();
89 lock (synchronization_lock) {
90 Logger.Log.Debug ("Synchronizing... (target={0})", target);
92 DirectoryInfo source_directory, target_directory;
93 source_directory = new DirectoryInfo ((target == SynchronizationTarget.Local) ? remote_index_dir : PathFinder.IndexDir);
94 target_directory = new DirectoryInfo ((target == SynchronizationTarget.Local) ? PathFinder.IndexDir : remote_index_dir);
96 if (SynchronizeDirectory (source_directory, target_directory))
97 Logger.Log.Debug ("Synchronized successfully in {0}", watch);
101 ////////////////////////////////////////////////////////////////
103 static private void SynchronizeHook (Scheduler.Task task)
105 try {
106 Synchronize (SynchronizationTarget.Remote);
107 } catch (Exception ex) {
108 Logger.Log.Error (ex, "Caught exception while synchronizing");
111 task.Reschedule = true;
112 task.TriggerTime = DateTime.Now.AddMinutes (sync_interval_in_minutes);
115 static private void ShutdownHook (Scheduler.Task task)
117 try {
118 Synchronize (SynchronizationTarget.Remote);
120 // FIXME: This may not be safe to do here
121 Logger.Log.Debug ("Purging locally synchronized indexes");
122 Directory.Delete (PathFinder.IndexDir, true);
123 } catch (Exception ex) {
124 Logger.Log.Error (ex, "Caught exception while doing shutdown synchronization");
128 ////////////////////////////////////////////////////////////////
130 // FIXME: Non-Getto synchronization
131 static private bool SynchronizeDirectory (DirectoryInfo source_directory,
132 DirectoryInfo target_directory)
134 if (! source_directory.Exists)
135 throw new Exception ("Synchronization error: Source directory does not exist");
137 DirectoryInfo target_directory_temp, target_directory_trash;
139 // Setup directories for the copy/move/move/delete procedure
140 target_directory_temp = new DirectoryInfo (target_directory.FullName + ".tmp");
141 target_directory_trash = new DirectoryInfo (target_directory.FullName + ".trash");
143 if (target_directory_temp.Exists)
144 target_directory_temp.Delete (true);
145 target_directory_temp.Create ();
147 try {
148 // Copy the directory structure and files
149 CopyDirectoryRecursively (source_directory, target_directory_temp);
151 if (target_directory_trash.Exists)
152 target_directory_trash.Delete (true);
154 target_directory.MoveTo (target_directory_trash.FullName);
155 target_directory_temp.MoveTo (target_directory.FullName);
157 target_directory_trash.Delete (true);
158 } catch (Exception ex) {
159 Logger.Log.Error (ex, "Caught error while synchronizing directory");
160 return false;
163 return true;
166 static private void CopyDirectoryRecursively (DirectoryInfo source_directory,
167 DirectoryInfo target_directory)
169 if (!target_directory.Exists)
170 target_directory.Create ();
172 foreach (FileInfo source_file in DirectoryWalker.GetFileInfos (source_directory)) {
173 FileInfo target_file = new FileInfo (Path.Combine (target_directory.FullName, source_file.Name));
175 // FIXME: Don't hard code filenames - Mono.Posix.StatMode.Regular
176 if (source_file.Name.IndexOf ("socket") != -1 ||
177 source_file.Name.EndsWith ("-journal"))
178 continue;
180 File.Copy (source_file.FullName, target_file.FullName, true);
183 foreach (DirectoryInfo source_child_directory in DirectoryWalker.GetDirectoryInfos (source_directory)) {
184 DirectoryInfo target_child_directory = new DirectoryInfo (Path.Combine (target_directory.FullName, source_child_directory.Name));
186 CopyDirectoryRecursively (source_child_directory,
187 target_child_directory);