4 // Copyright (C) 2005 Novell, Inc.
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.
33 namespace Beagle
.Daemon
.FileSystemQueryable
{
35 public class CrawlTask
: Scheduler
.Task
{
37 FileSystemQueryable queryable
;
38 IIndexableGenerator current_generator
;
40 private bool active
= true;
42 get { return active; }
45 public CrawlTask (FileSystemQueryable queryable
)
47 this.queryable
= queryable
;
48 this.Tag
= "File System Crawler";
49 this.Priority
= Scheduler
.Priority
.Generator
;
52 private class PostCrawlClosure
{
53 public FileSystemModel Model
;
54 public FileSystemModel
.Directory Directory
;
55 public DateTime CrawlTime
;
59 Model
.MarkAsCrawled (Directory
, CrawlTime
);
64 protected override void DoTaskReal ()
66 // If our last generator is still doing stuff, just reschedule
67 // and return. This keeps us from generating more tasks until
68 // the last one we started runs to completion.
69 if (current_generator
!= null && current_generator
.HasNextIndexable ()) {
74 FileSystemModel model
= queryable
.Model
;
76 current_generator
= null;
78 FileSystemModel
.Directory next_dir
= model
.GetNextDirectoryToCrawl ();
79 if (next_dir
== null) {
84 int uncrawled
= model
.GetUncrawledCounts ();
85 this.Description
= String
.Format ("last={0}, uncrawled={1}",
86 next_dir
.FullName
, uncrawled
);
88 Logger
.Log
.Debug ("Crawl Task Scheduling {0} (state={1})", next_dir
.FullName
, next_dir
.State
);
90 if (! model
.ScanSubdirs (next_dir
))
93 // We want this task to get re-scheduled after it is run.
96 // ...but if we are crawling a possibly-clean directory,
97 // maybe wait a little bit extra.
98 if (Environment
.GetEnvironmentVariable ("BEAGLE_EXERCISE_THE_DOG") == null)
99 TriggerTime
= DateTime
.Now
.AddSeconds (5);
101 if (next_dir
== null)
104 // We no longer care about the Open event
105 model
.DropOpenWatch (next_dir
);
107 // Set up a task group to mark the time on the directory
108 // after we finish crawling it.
109 PostCrawlClosure closure
= new PostCrawlClosure ();
110 closure
.Model
= model
;
111 closure
.Directory
= next_dir
;
112 closure
.CrawlTime
= DateTime
.Now
;
113 Scheduler
.TaskGroup
group = Scheduler
.NewTaskGroup ("Crawl " + next_dir
.FullName
, null,
114 new Scheduler
.Hook (closure
.Hook
));
116 // Construct an indexable generator and add it to the scheduler
117 current_generator
= new DirectoryIndexableGenerator (queryable
, next_dir
);
118 Scheduler
.Task task
= queryable
.NewAddTask (current_generator
);
119 task
.AddTaskGroup (group);
120 ThisScheduler
.Add (task
, Scheduler
.AddType
.OptionallyReplaceExisting
);