content_server 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/content_data/content_data.rb +194 -56
- data/lib/content_data/version.rb +1 -1
- data/lib/content_server/backup_server.rb +4 -27
- data/lib/content_server/content_server.rb +3 -27
- data/lib/content_server/file_streamer.rb +2 -0
- data/lib/content_server/remote_content.rb +1 -2
- data/lib/content_server/server.rb +23 -3
- data/lib/content_server/version.rb +1 -1
- data/lib/email/version.rb +1 -1
- data/lib/file_copy/version.rb +1 -1
- data/lib/file_indexing/index_agent.rb +1 -1
- data/lib/file_indexing/version.rb +1 -1
- data/lib/file_monitoring/file_monitoring.rb +45 -32
- data/lib/file_monitoring/monitor_path.rb +219 -181
- data/lib/file_monitoring/version.rb +1 -1
- data/lib/file_utils/file_generator/file_generator.rb +1 -1
- data/lib/file_utils/file_utils.rb +2 -2
- data/lib/file_utils/version.rb +1 -1
- data/lib/log/version.rb +1 -1
- data/lib/networking/version.rb +1 -1
- data/lib/params/version.rb +1 -1
- data/lib/process_monitoring/version.rb +1 -1
- data/lib/run_in_background/version.rb +1 -1
- data/lib/testing_memory/testing_memory.rb +1 -1
- data/lib/testing_server/testing_server.rb +1 -1
- data/lib/testing_server/version.rb +1 -1
- data/spec/content_data/validations_spec.rb +2 -2
- data/spec/content_server/file_streamer_spec.rb +5 -0
- data/spec/networking/tcp_spec.rb +1 -3
- data/spec/validations/index_validations_spec.rb +2 -2
- data/test/content_data/content_data_test.rb +8 -7
- data/test/file_generator/file_generator_spec.rb +3 -2
- data/test/file_monitoring/monitor_path_test.rb +38 -4
- data/test/file_utils/fileutil_mksymlink_test.rb +9 -0
- data/test/file_utils/time_modification_test.rb +6 -2
- data/test/run_in_background/test_app +17 -15
- metadata +2 -93
- data/lib/content_server/queue_indexer.rb +0 -86
- data/test/file_indexing/index_agent_test.rb +0 -51
- data/test/file_indexing/index_agent_test/New.txt +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libexslt.dll +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libxslt.dll +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/xsltproc.exe +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exslt.h +0 -102
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltconfig.h +0 -73
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltexports.h +0 -140
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/libexslt.h +0 -29
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/attributes.h +0 -38
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/documents.h +0 -93
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extensions.h +0 -262
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extra.h +0 -80
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/functions.h +0 -78
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/imports.h +0 -75
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/keys.h +0 -53
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/libxslt.h +0 -30
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/namespaces.h +0 -68
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/numbersInternals.h +0 -69
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/pattern.h +0 -81
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/preproc.h +0 -43
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/security.h +0 -104
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/templates.h +0 -77
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/transform.h +0 -207
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/trio.h +0 -216
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/triodef.h +0 -220
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/variables.h +0 -91
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/win32config.h +0 -101
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xslt.h +0 -103
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltInternals.h +0 -1967
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltconfig.h +0 -172
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltexports.h +0 -142
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltlocale.h +0 -57
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltutils.h +0 -309
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltwin32config.h +0 -105
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt_a.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt_a.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/readme.txt +0 -22
- data/test/file_indexing/index_agent_test/patterns.input +0 -3
- data/test/file_monitoring/file_monitoring_test.rb +0 -0
- data/test/file_monitoring/file_monitoring_test/conf.yml +0 -4
- data/test/file_monitoring/file_monitoring_test/conf_win32.yml +0 -5
- data/test/file_monitoring/file_monitoring_test/log +0 -56
@@ -29,6 +29,8 @@ module ContentData
|
|
29
29
|
# instances which was added to @contents_info
|
30
30
|
class ContentData
|
31
31
|
|
32
|
+
CHUNK_SIZE = 5000
|
33
|
+
|
32
34
|
def initialize(other = nil)
|
33
35
|
if other.nil?
|
34
36
|
@contents_info = {} # Checksum --> [size, paths-->time(instance), time(content)]
|
@@ -46,34 +48,44 @@ module ContentData
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def clone_instances_info
|
49
|
-
|
51
|
+
clone_instances_info = {}
|
52
|
+
instances_info_enum = @instances_info.each_key
|
53
|
+
loop {
|
54
|
+
location = instances_info_enum.next rescue break
|
50
55
|
clone_instances_info[[location[0].clone, location[1].clone]] = @instances_info[location].clone
|
51
|
-
clone_instances_info
|
52
56
|
}
|
57
|
+
clone_instances_info
|
53
58
|
end
|
54
59
|
|
55
60
|
def clone_contents_info
|
56
|
-
|
61
|
+
clone_contents_info = {}
|
62
|
+
contents_info_enum = @contents_info.each_key
|
63
|
+
loop {
|
64
|
+
checksum = contents_info_enum.next rescue break
|
57
65
|
instances = @contents_info[checksum]
|
58
66
|
size = instances[0]
|
59
67
|
content_time = instances[2]
|
60
68
|
instances_db = instances[1]
|
61
69
|
instances_db_cloned = {}
|
62
|
-
instances_db.
|
70
|
+
instances_db_enum = instances_db.each_key
|
71
|
+
loop {
|
72
|
+
location = instances_db_enum.next rescue break
|
63
73
|
instance_mtime = instances_db[location]
|
64
74
|
instances_db_cloned[[location[0].clone,location[1].clone]]=instance_mtime
|
65
75
|
}
|
66
76
|
clone_contents_info[checksum] = [size,
|
67
77
|
instances_db_cloned,
|
68
78
|
content_time]
|
69
|
-
clone_contents_info
|
70
79
|
}
|
80
|
+
clone_contents_info
|
71
81
|
end
|
72
82
|
|
73
83
|
# iterator over @contents_info data structure (not including instances)
|
74
84
|
# block is provided with: checksum, size and content modification time
|
75
85
|
def each_content(&block)
|
76
|
-
@contents_info.
|
86
|
+
contents_enum = @contents_info.each_key
|
87
|
+
loop {
|
88
|
+
checksum = contents_enum.next rescue break
|
77
89
|
content_val = @contents_info[checksum]
|
78
90
|
# provide checksum, size and content modification time to the block
|
79
91
|
block.call(checksum,content_val[0], content_val[2])
|
@@ -84,9 +96,13 @@ module ContentData
|
|
84
96
|
# block is provided with: checksum, size, content modification time,
|
85
97
|
# instance modification time, server and file path
|
86
98
|
def each_instance(&block)
|
87
|
-
@contents_info.
|
99
|
+
contents_enum = @contents_info.each_key
|
100
|
+
loop {
|
101
|
+
checksum = contents_enum.next rescue break
|
88
102
|
content_info = @contents_info[checksum]
|
89
|
-
content_info[1].
|
103
|
+
content_info_enum = content_info[1].each_key
|
104
|
+
loop {
|
105
|
+
location = content_info_enum.next rescue break
|
90
106
|
# provide the block with: checksum, size, content modification time,instance modification time,
|
91
107
|
# server and path.
|
92
108
|
instance_modification_time = content_info[1][location]
|
@@ -101,7 +117,9 @@ module ContentData
|
|
101
117
|
# instance modification time, server and file path
|
102
118
|
def content_each_instance(checksum, &block)
|
103
119
|
content_info = @contents_info[checksum]
|
104
|
-
content_info[1].
|
120
|
+
instances_db_enum = content_info[1].each_key
|
121
|
+
loop {
|
122
|
+
location = instances_db_enum.next rescue break
|
105
123
|
# provide the block with: checksum, size, content modification time,instance modification time,
|
106
124
|
# server and path.
|
107
125
|
instance_modification_time = content_info[1][location]
|
@@ -115,11 +133,7 @@ module ContentData
|
|
115
133
|
end
|
116
134
|
|
117
135
|
def instances_size()
|
118
|
-
|
119
|
-
@contents_info.values.each { |content_info|
|
120
|
-
counter += content_info[1].length
|
121
|
-
}
|
122
|
-
counter
|
136
|
+
@instances_info.length
|
123
137
|
end
|
124
138
|
|
125
139
|
def checksum_instances_size(checksum)
|
@@ -137,6 +151,13 @@ module ContentData
|
|
137
151
|
|
138
152
|
def add_instance(checksum, size, server, path, modification_time)
|
139
153
|
location = [server, path]
|
154
|
+
|
155
|
+
# file was changed but remove_instance was not called
|
156
|
+
if (@instances_info.include?(location) && @instances_info[location] != checksum)
|
157
|
+
Log.warning("#{server}:#{path} file already exists with different checksum")
|
158
|
+
remove_instance(server, path)
|
159
|
+
end
|
160
|
+
|
140
161
|
content_info = @contents_info[checksum]
|
141
162
|
if content_info.nil?
|
142
163
|
@contents_info[checksum] = [size,
|
@@ -186,8 +207,10 @@ module ContentData
|
|
186
207
|
# found records are removed from both @instances_info and @instances_info.
|
187
208
|
# input params: server & dir_to_remove - are used to check each instance unique key (called location)
|
188
209
|
# removes also content\s, if a content\s become\s empty after removing instance\s
|
189
|
-
def remove_directory(
|
190
|
-
@contents_info.
|
210
|
+
def remove_directory(dir_to_remove, server)
|
211
|
+
contents_enum = @contents_info.each_key
|
212
|
+
loop {
|
213
|
+
checksum = contents_enum.next rescue break
|
191
214
|
instances = @contents_info[checksum][1]
|
192
215
|
instances.each_key { |location|
|
193
216
|
if location[0] == server and location[1].scan(dir_to_remove).size > 0
|
@@ -247,70 +270,181 @@ module ContentData
|
|
247
270
|
return_str
|
248
271
|
end
|
249
272
|
|
273
|
+
# Write content data to file.
|
274
|
+
# Write is using chunks (for both content chunks and instances chunks)
|
275
|
+
# Chunk is used to maximize GC affect. The temporary memory of each chunk is GCed.
|
276
|
+
# Without the chunks used in a dipper stack level, GC keeps the temporary objects as part of the stack context.
|
250
277
|
def to_file(filename)
|
251
278
|
content_data_dir = File.dirname(filename)
|
252
279
|
FileUtils.makedirs(content_data_dir) unless File.directory?(content_data_dir)
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
280
|
+
File.open(filename, 'w') { |file|
|
281
|
+
file.write("#{@contents_info.length}\n")
|
282
|
+
contents_enum = @contents_info.each_key
|
283
|
+
content_chunks = @contents_info.length / CHUNK_SIZE + 1
|
284
|
+
chunks_counter = 0
|
285
|
+
while chunks_counter < content_chunks
|
286
|
+
to_file_contents_chunk(file,contents_enum, CHUNK_SIZE)
|
287
|
+
GC.start
|
288
|
+
chunks_counter += 1
|
289
|
+
end
|
290
|
+
file.write("#{@instances_info.length}\n")
|
291
|
+
contents_enum = @contents_info.each_key
|
292
|
+
chunks_counter = 0
|
293
|
+
while chunks_counter < content_chunks
|
294
|
+
to_file_instances_chunk(file,contents_enum, CHUNK_SIZE)
|
295
|
+
GC.start
|
296
|
+
chunks_counter += 1
|
297
|
+
end
|
261
298
|
}
|
262
|
-
|
299
|
+
end
|
300
|
+
|
301
|
+
def to_file_contents_chunk(file, contents_enum, chunk_size)
|
302
|
+
chunk_counter = 0
|
303
|
+
while chunk_counter < chunk_size
|
304
|
+
checksum = contents_enum.next rescue return
|
305
|
+
content_info = @contents_info[checksum]
|
306
|
+
file.write("#{checksum},#{content_info[0]},#{content_info[2]}\n")
|
307
|
+
chunk_counter += 1
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def to_file_instances_chunk(file, contents_enum, chunk_size)
|
312
|
+
chunk_counter = 0
|
313
|
+
while chunk_counter < chunk_size
|
314
|
+
checksum = contents_enum.next rescue return
|
315
|
+
content_info = @contents_info[checksum]
|
316
|
+
instances_db_enum = content_info[1].each_key
|
317
|
+
loop {
|
318
|
+
location = instances_db_enum.next rescue break
|
319
|
+
# provide the block with: checksum, size, content modification time,instance modification time,
|
320
|
+
# server and path.
|
321
|
+
instance_modification_time = content_info[1][location]
|
322
|
+
file.write("#{checksum},#{content_info[0]},#{location[0]},#{location[1]},#{instance_modification_time}\n")
|
323
|
+
}
|
324
|
+
chunk_counter += 1
|
325
|
+
break if chunk_counter == chunk_size
|
326
|
+
end
|
263
327
|
end
|
264
328
|
|
265
329
|
# TODO validation that file indeed contains ContentData missing
|
330
|
+
# Loading db from file using chunks for better memory performance
|
266
331
|
def from_file(filename)
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
332
|
+
# read first line (number of contents)
|
333
|
+
# calculate line number (number of instances)
|
334
|
+
# read number of instances.
|
335
|
+
# loop over instances lines (using chunks) and add instances
|
336
|
+
|
337
|
+
File.open(filename, 'r') { |file|
|
338
|
+
# Get number of contents (at first line)
|
339
|
+
number_of_contents = file.gets # this gets the next line or return nil at EOF
|
340
|
+
unless (number_of_contents and number_of_contents.match(/^[\d]+$/)) # check that line is of Number format
|
341
|
+
return reset_load_from_file(filename, file, "number of contents should be a number. We got:#{number_of_contents}")
|
342
|
+
end
|
343
|
+
number_of_contents = number_of_contents.to_i
|
344
|
+
# advance file lines over all contents. We need only the instances data to build the content data object
|
345
|
+
# use chunks and GC
|
346
|
+
contents_chunks = number_of_contents / CHUNK_SIZE
|
347
|
+
contents_chunks += 1 if (contents_chunks * CHUNK_SIZE < number_of_contents)
|
348
|
+
chunk_index = 0
|
349
|
+
while chunk_index < contents_chunks
|
350
|
+
chunk_size = CHUNK_SIZE
|
351
|
+
if chunk_index + 1 == contents_chunks
|
352
|
+
# update last chunk size
|
353
|
+
chunk_size = number_of_contents - (chunk_index * CHUNK_SIZE)
|
287
354
|
end
|
355
|
+
return unless read_contents_chunk(filename, file, chunk_size)
|
356
|
+
GC.start
|
357
|
+
chunk_index += 1
|
358
|
+
end
|
288
359
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
360
|
+
# get number of instances
|
361
|
+
number_of_instances = file.gets
|
362
|
+
unless (number_of_instances and number_of_instances.match(/^[\d]+$/)) # check that line is of Number format
|
363
|
+
return reset_load_from_file(filename, file, "number of instances should be a Number. We got:#{number_of_instances}")
|
364
|
+
end
|
365
|
+
number_of_instances = number_of_instances.to_i
|
366
|
+
# read in instances chunks and GC
|
367
|
+
instances_chunks = number_of_instances / CHUNK_SIZE
|
368
|
+
instances_chunks += 1 if (instances_chunks * CHUNK_SIZE < number_of_instances)
|
369
|
+
chunk_index = 0
|
370
|
+
while chunk_index < instances_chunks
|
371
|
+
chunk_size = CHUNK_SIZE
|
372
|
+
if chunk_index + 1 == instances_chunks
|
373
|
+
# update last chunk size
|
374
|
+
chunk_size = number_of_instances - (chunk_index * CHUNK_SIZE)
|
375
|
+
end
|
376
|
+
return unless read_instances_chunk(filename, file, chunk_size)
|
377
|
+
GC.start
|
378
|
+
chunk_index += 1
|
294
379
|
end
|
295
|
-
i += 1
|
296
380
|
}
|
297
381
|
end
|
298
382
|
|
383
|
+
def read_contents_chunk(filename, file, chunk_size)
|
384
|
+
chunk_index = 0
|
385
|
+
while chunk_index < chunk_size
|
386
|
+
return reset_load_from_file(filename, file, "Expecting content line but " +
|
387
|
+
"reached end of file after line #{$.}") unless file.gets
|
388
|
+
chunk_index += 1
|
389
|
+
end
|
390
|
+
true
|
391
|
+
end
|
392
|
+
|
393
|
+
def read_instances_chunk(filename, file, chunk_size)
|
394
|
+
chunk_index = 0
|
395
|
+
while chunk_index < chunk_size
|
396
|
+
instance_line = file.gets
|
397
|
+
return reset_load_from_file(filename, file, "Expected to read Instance line but reached EOF") unless instance_line
|
398
|
+
parameters = instance_line.split(',')
|
399
|
+
# bugfix: if file name consist a comma then parsing based on comma separating fails
|
400
|
+
if (parameters.size > 5)
|
401
|
+
(4..parameters.size-2).each do |i|
|
402
|
+
parameters[3] = [parameters[3], parameters[i]].join(",")
|
403
|
+
end
|
404
|
+
(4..parameters.size-2).each do |i|
|
405
|
+
parameters.delete_at(4)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
add_instance(parameters[0],
|
410
|
+
parameters[1].to_i,
|
411
|
+
parameters[2],
|
412
|
+
parameters[3],
|
413
|
+
parameters[4].to_i)
|
414
|
+
chunk_index += 1
|
415
|
+
end
|
416
|
+
true
|
417
|
+
end
|
418
|
+
|
419
|
+
def reset_load_from_file(file_name, file_io, err_msg)
|
420
|
+
Log.error("unexpected error reading file:#{file_name}\nError message:#{err_msg}")
|
421
|
+
@contents_info = {} # Checksum --> [size, paths-->time(instance), time(content)]
|
422
|
+
@instances_info = {} # location --> checksum to optimize instances query
|
423
|
+
file_io.close
|
424
|
+
nil
|
425
|
+
end
|
426
|
+
|
299
427
|
# for each content, all time fields (content and instances) are replaced with the
|
300
428
|
# min time found, while going through all time fields.
|
301
429
|
def unify_time()
|
302
|
-
@contents_info.
|
430
|
+
contents_enum = @contents_info.each_key
|
431
|
+
loop {
|
432
|
+
checksum = contents_enum.next rescue break
|
303
433
|
content_info = @contents_info[checksum]
|
304
434
|
min_time_per_checksum = content_info[2]
|
305
435
|
instances = content_info[1]
|
306
|
-
instances.
|
436
|
+
instances_enum = instances.each_key
|
437
|
+
loop {
|
438
|
+
location = instances_enum.next rescue break
|
307
439
|
instance_mod_time = instances[location]
|
308
440
|
if instance_mod_time < min_time_per_checksum
|
309
441
|
min_time_per_checksum = instance_mod_time
|
310
442
|
end
|
311
443
|
}
|
312
444
|
# update all instances with min time
|
313
|
-
instances.
|
445
|
+
instances_enum = instances.each_key
|
446
|
+
loop {
|
447
|
+
location = instances_enum.next rescue break
|
314
448
|
instances[location] = min_time_per_checksum
|
315
449
|
}
|
316
450
|
# update content time with min time
|
@@ -353,11 +487,15 @@ module ContentData
|
|
353
487
|
end
|
354
488
|
|
355
489
|
is_valid = true
|
356
|
-
@contents_info.
|
490
|
+
contents_enum = @contents_info.each_key
|
491
|
+
loop {
|
492
|
+
checksum = contents_enum.next rescue break
|
357
493
|
instances = @contents_info[checksum]
|
358
494
|
content_size = instances[0]
|
359
495
|
content_mtime = instances[2]
|
360
|
-
instances[1].
|
496
|
+
instances_enum = instances[1].each_key
|
497
|
+
loop {
|
498
|
+
unique_path = instances_enum.next rescue break
|
361
499
|
instance_mtime = instances[1][unique_path]
|
362
500
|
instance_info = [checksum, content_mtime, content_size, instance_mtime]
|
363
501
|
instance_info.concat(unique_path)
|
data/lib/content_data/version.rb
CHANGED
@@ -4,7 +4,6 @@ require 'thread'
|
|
4
4
|
|
5
5
|
require 'content_data'
|
6
6
|
require 'content_server/content_receiver'
|
7
|
-
require 'content_server/queue_indexer'
|
8
7
|
require 'content_server/queue_copy'
|
9
8
|
require 'content_server/remote_content'
|
10
9
|
require 'content_server/server'
|
@@ -57,14 +56,14 @@ module ContentServer
|
|
57
56
|
# initial global local content data object
|
58
57
|
$local_content_data_lock = Mutex.new
|
59
58
|
$local_content_data = ContentData::ContentData.new
|
59
|
+
$last_content_data_id = $local_content_data.unique_id
|
60
60
|
|
61
61
|
# Read here for initial content data that exist from previous system run
|
62
62
|
content_data_path = Params['local_content_data_path']
|
63
|
-
last_content_data_id = nil
|
64
63
|
if File.exists?(content_data_path) and !File.directory?(content_data_path)
|
65
64
|
Log.info("reading initial content data that exist from previous system run from file:%s", content_data_path)
|
66
65
|
$local_content_data.from_file(content_data_path)
|
67
|
-
last_content_data_id = $local_content_data.unique_id
|
66
|
+
$last_content_data_id = $local_content_data.unique_id
|
68
67
|
else
|
69
68
|
if File.directory?(content_data_path)
|
70
69
|
raise("Param:'local_content_data_path':'%s' cannot be a directory name", Params['local_content_data_path'])
|
@@ -75,21 +74,13 @@ module ContentServer
|
|
75
74
|
end
|
76
75
|
|
77
76
|
Log.info("Init monitoring")
|
78
|
-
monitoring_events = Queue.new
|
79
77
|
fm = FileMonitoring::FileMonitoring.new()
|
80
|
-
|
78
|
+
|
81
79
|
# Start monitoring and writing changes to queue
|
82
80
|
all_threads << Thread.new do
|
83
81
|
fm.monitor_files
|
84
82
|
end
|
85
83
|
|
86
|
-
# # # # # # # # # # # # # #
|
87
|
-
# Initialize/Start local indexer
|
88
|
-
Log.debug1('Start indexer')
|
89
|
-
queue_indexer = QueueIndexer.new(monitoring_events)
|
90
|
-
# Start indexing on demand and write changes to queue
|
91
|
-
all_threads << queue_indexer.run
|
92
|
-
|
93
84
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
94
85
|
# thread: Start dump local content data to file
|
95
86
|
Log.debug1('Init thread: flush local content data to file')
|
@@ -97,21 +88,7 @@ module ContentServer
|
|
97
88
|
FileUtils.mkdir_p(Params['tmp_path']) unless File.directory?(Params['tmp_path'])
|
98
89
|
loop{
|
99
90
|
sleep(Params['data_flush_delay'])
|
100
|
-
|
101
|
-
$testing_memory_log.info('Start flush content data to file') if $testing_memory_active
|
102
|
-
written_to_file = false
|
103
|
-
$local_content_data_lock.synchronize{
|
104
|
-
local_content_data_unique_id = $local_content_data.unique_id
|
105
|
-
if (local_content_data_unique_id != last_content_data_id)
|
106
|
-
last_content_data_id = local_content_data_unique_id
|
107
|
-
$local_content_data.to_file($tmp_content_data_file)
|
108
|
-
written_to_file = true
|
109
|
-
else
|
110
|
-
Log.info('no need to flush. content data has not changed')
|
111
|
-
end
|
112
|
-
}
|
113
|
-
File.rename($tmp_content_data_file, Params['local_content_data_path']) if written_to_file
|
114
|
-
$testing_memory_log.info("End flush content data to file") if $testing_memory_active
|
91
|
+
ContentServer.flush_content_data
|
115
92
|
}
|
116
93
|
end
|
117
94
|
|
@@ -4,7 +4,6 @@ require 'thread'
|
|
4
4
|
|
5
5
|
require 'content_data'
|
6
6
|
require 'content_server/content_receiver'
|
7
|
-
require 'content_server/queue_indexer'
|
8
7
|
require 'content_server/queue_copy'
|
9
8
|
require 'content_server/remote_content'
|
10
9
|
require 'file_indexing'
|
@@ -46,14 +45,14 @@ module ContentServer
|
|
46
45
|
# initial global local content data object
|
47
46
|
$local_content_data_lock = Mutex.new
|
48
47
|
$local_content_data = ContentData::ContentData.new
|
48
|
+
$last_content_data_id = $local_content_data.unique_id
|
49
49
|
|
50
50
|
# Read here for initial content data that exist from previous system run
|
51
51
|
content_data_path = Params['local_content_data_path']
|
52
|
-
last_content_data_id = nil
|
53
52
|
if File.exists?(content_data_path) and !File.directory?(content_data_path)
|
54
53
|
Log.info("reading initial content data that exist from previous system run from file:%s", content_data_path)
|
55
54
|
$local_content_data.from_file(content_data_path)
|
56
|
-
last_content_data_id = $local_content_data.unique_id
|
55
|
+
$last_content_data_id = $local_content_data.unique_id
|
57
56
|
else
|
58
57
|
if File.directory?(content_data_path)
|
59
58
|
raise("Param:'local_content_data_path':'%s'cannot be a directory name", Params['local_content_data_path'])
|
@@ -64,21 +63,12 @@ module ContentServer
|
|
64
63
|
end
|
65
64
|
|
66
65
|
Log.info('Init monitoring')
|
67
|
-
monitoring_events = Queue.new
|
68
66
|
fm = FileMonitoring::FileMonitoring.new()
|
69
|
-
fm.set_event_queue(monitoring_events)
|
70
67
|
# Start monitoring and writing changes to queue
|
71
68
|
all_threads << Thread.new do
|
72
69
|
fm.monitor_files
|
73
70
|
end
|
74
71
|
|
75
|
-
# # # # # # # # # # # # # #
|
76
|
-
# Initialize/Start local indexer
|
77
|
-
Log.debug1('Start indexer')
|
78
|
-
queue_indexer = QueueIndexer.new(monitoring_events)
|
79
|
-
# Start indexing on demand and write changes to queue
|
80
|
-
all_threads << queue_indexer.run
|
81
|
-
|
82
72
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
83
73
|
# thread: Start dump local content data to file
|
84
74
|
Log.debug1('Init thread: flush local content data to file')
|
@@ -86,21 +76,7 @@ module ContentServer
|
|
86
76
|
FileUtils.mkdir_p(Params['tmp_path']) unless File.directory?(Params['tmp_path'])
|
87
77
|
loop{
|
88
78
|
sleep(Params['data_flush_delay'])
|
89
|
-
|
90
|
-
$testing_memory_log.info('Start flush content data to file') if $testing_memory_active
|
91
|
-
written_to_file = false
|
92
|
-
$local_content_data_lock.synchronize{
|
93
|
-
local_content_data_unique_id = $local_content_data.unique_id
|
94
|
-
if (local_content_data_unique_id != last_content_data_id)
|
95
|
-
last_content_data_id = local_content_data_unique_id
|
96
|
-
$local_content_data.to_file($tmp_content_data_file)
|
97
|
-
written_to_file = true
|
98
|
-
else
|
99
|
-
Log.info('no need to flush. content data has not changed')
|
100
|
-
end
|
101
|
-
}
|
102
|
-
File.rename($tmp_content_data_file, Params['local_content_data_path']) if written_to_file
|
103
|
-
$testing_memory_log.info("End flush content data to file") if $testing_memory_active
|
79
|
+
ContentServer.flush_content_data
|
104
80
|
}
|
105
81
|
end
|
106
82
|
|