xapian_db 0.5.9 → 0.5.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/README.rdoc +24 -6
- data/Rakefile +1 -1
- data/lib/generators/install_generator.rb +17 -0
- data/lib/generators/templates/beanstalk_worker +71 -0
- data/lib/xapian_db/index_writers/no_op_writer.rb +29 -0
- data/lib/xapian_db/railtie.rb +22 -17
- data/lib/xapian_db.rb +33 -13
- data/tasks/beanstalk_worker.rake +11 -3
- data/xapian_source/xapian-bindings-1.2.5.tar.gz +0 -0
- data/xapian_source/xapian-core-1.2.5.tar.gz +0 -0
- metadata +29 -11
- data/xapian_source/xapian-bindings-1.2.4.tar.gz +0 -0
- data/xapian_source/xapian-core-1.2.4.tar.gz +0 -0
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
##0.5.10 (April 6th, 2011)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- the beanstalk worker is now implemented as a daemon script (execute 'rails generate xapian_db:install' to install it)
|
6
|
+
- execute a block with auto indexing disabled (see 'Bulk inserts / updates / deletes' in teh README)
|
7
|
+
- updated the xapian source to version 1.2.5
|
8
|
+
|
1
9
|
##0.5.9 (March 25th, 2011)
|
2
10
|
|
3
11
|
Fixes:
|
data/README.rdoc
CHANGED
@@ -244,6 +244,19 @@ only if the block does not raise an exception.
|
|
244
244
|
object2.save
|
245
245
|
end
|
246
246
|
|
247
|
+
=== Bulk inserts / updates / deletes
|
248
|
+
|
249
|
+
When you change a lot of models, it is not very efficient to update the xapian index on each insert / update / delete. Instead,
|
250
|
+
you can use the auto_indexing_disabled method with a block and rebuild the whole index afterwards:
|
251
|
+
|
252
|
+
XapianDb.auto_indexing_disabled do
|
253
|
+
Person.each do |person|
|
254
|
+
# change person
|
255
|
+
person.save
|
256
|
+
end
|
257
|
+
end
|
258
|
+
Person.rebuild_xapian_index
|
259
|
+
|
247
260
|
== Production setup
|
248
261
|
|
249
262
|
Since Xapian allows only one database instance to write to the index, the default setup of XapianDb will not work
|
@@ -282,21 +295,26 @@ The easiest way is to use macports or homebrew:
|
|
282
295
|
gem 'beanstalk-client' # Add this to your Gemfile
|
283
296
|
bundle install
|
284
297
|
|
285
|
-
=== 3.
|
298
|
+
=== 3. Install the beanstalk worker script
|
299
|
+
|
300
|
+
rails generate xapian:db install
|
301
|
+
|
302
|
+
=== 4. Configure your production environment in config/xapian_db.yml
|
286
303
|
|
287
304
|
production:
|
288
305
|
database: db/xapian_db/production
|
289
306
|
writer: beanstalk
|
290
307
|
beanstalk_daemon: localhost:11300
|
291
308
|
|
292
|
-
===
|
309
|
+
=== 5. start the beanstalk daemon
|
293
310
|
|
294
311
|
beanstalkd -d
|
295
312
|
|
296
|
-
===
|
297
|
-
|
298
|
-
rake RAILS_ENV=production xapian_db:beanstalk_worker
|
313
|
+
=== 6. start the beanstalk worker from within your Rails app root directory
|
299
314
|
|
300
|
-
|
315
|
+
RAILS_ENV=production script/beanstalk_worker start
|
301
316
|
|
317
|
+
If everything is fine, you should find a file namend beanstalk_worker.pid in tmp/pids. If something
|
318
|
+
goes wrong, you'll find beanstalk_worker.log instead showing the stack trace.
|
302
319
|
|
320
|
+
<b>Important: Do not start multiple instances of this daemon!</b>
|
data/Rakefile
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module XapianDb
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
desc "Creates a beanstalk worker script."
|
9
|
+
|
10
|
+
def copy_script
|
11
|
+
copy_file "beanstalk_worker", "script/beanstalk_worker"
|
12
|
+
chmod "script/beanstalk_worker", 0755
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require 'rails'
|
6
|
+
require 'daemons'
|
7
|
+
require "xapian_db"
|
8
|
+
require 'yaml'
|
9
|
+
require 'rails/railtie' # execute xapian_db railtie
|
10
|
+
|
11
|
+
# daemon script to manage the beanstalk worker daemon
|
12
|
+
# @author Gernot Kogler
|
13
|
+
module XapianDb
|
14
|
+
class BeanstalkWorker
|
15
|
+
|
16
|
+
def process_requests
|
17
|
+
|
18
|
+
Rails.logger.info "XapianDb beanstalk worker: initializing..."
|
19
|
+
|
20
|
+
url = XapianDb::Config.beanstalk_daemon_url
|
21
|
+
beanstalk = Beanstalk::Pool.new([url])
|
22
|
+
worker = XapianDb::IndexWriters::BeanstalkWorker.new
|
23
|
+
Rails.logger.info "XapianDb beanstalk worker: ready"
|
24
|
+
|
25
|
+
loop do
|
26
|
+
begin
|
27
|
+
job = beanstalk.reserve
|
28
|
+
params = YAML::load job.body
|
29
|
+
Rails.logger.info "XapianDb beanstalk worker: executing task #{params}"
|
30
|
+
task = params.delete :task
|
31
|
+
worker.send task, params
|
32
|
+
rescue Exception => ex
|
33
|
+
Rails.logger.error "XapianDb beanstalk worker: could not process #{job.body} (#{ex})"
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
job.delete
|
38
|
+
rescue Exception => ex
|
39
|
+
Rails.logger.error "XapianDb beanstalk worker: could delete job #{job.body} (#{ex})"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# =========================================================================================
|
48
|
+
# daemon setup
|
49
|
+
# =========================================================================================
|
50
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
51
|
+
pids_dir = File.join(dir, 'tmp', 'pids')
|
52
|
+
FileUtils.makedirs pids_dir unless File.exists?(pids_dir)
|
53
|
+
|
54
|
+
daemon_options = {
|
55
|
+
:multiple => false,
|
56
|
+
:dir_mode => :normal,
|
57
|
+
:dir => pids_dir,
|
58
|
+
:backtrace => true
|
59
|
+
}
|
60
|
+
|
61
|
+
Daemons.run_proc('beanstalk_worker', daemon_options) do
|
62
|
+
if ARGV.include?('--')
|
63
|
+
ARGV.slice! 0..ARGV.index('--')
|
64
|
+
else
|
65
|
+
ARGV.clear
|
66
|
+
end
|
67
|
+
|
68
|
+
Dir.chdir dir
|
69
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
|
70
|
+
XapianDb::BeanstalkWorker.new.process_requests
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This writer is a dummy writer that simply does nothing.
|
4
|
+
# @author Gernot Kogler
|
5
|
+
|
6
|
+
module XapianDb
|
7
|
+
module IndexWriters
|
8
|
+
|
9
|
+
class NoOpWriter
|
10
|
+
|
11
|
+
# Update an object in the index
|
12
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
13
|
+
def index(obj); end
|
14
|
+
|
15
|
+
# Remove an object from the index
|
16
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
17
|
+
def unindex(obj); end
|
18
|
+
|
19
|
+
# Reindex all objects of a given class
|
20
|
+
# @param [Class] klass The class to reindex
|
21
|
+
# @param [Hash] options Options for reindexing
|
22
|
+
# @option options [Boolean] :verbose (false) Should the reindexing give status informations?
|
23
|
+
def reindex_class(klass, options={})
|
24
|
+
raise "rebuild_xapian_index is not supported inside a block with auto indexing disabled"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/xapian_db/railtie.rb
CHANGED
@@ -9,11 +9,16 @@ module XapianDb
|
|
9
9
|
# @author Gernot Kogler
|
10
10
|
class Railtie < ::Rails::Railtie
|
11
11
|
|
12
|
-
#
|
12
|
+
# require our rake tasks
|
13
13
|
rake_tasks do
|
14
14
|
load "#{File.dirname(__FILE__)}/../../tasks/beanstalk_worker.rake"
|
15
15
|
end
|
16
16
|
|
17
|
+
# require our generators
|
18
|
+
generators do
|
19
|
+
require "#{File.dirname(__FILE__)}/../generators/install_generator.rb"
|
20
|
+
end
|
21
|
+
|
17
22
|
config.before_configuration do
|
18
23
|
|
19
24
|
# Read the database configuration file if there is one
|
@@ -49,24 +54,24 @@ module XapianDb
|
|
49
54
|
load blueprints_file_path if File.exist?(blueprints_file_path)
|
50
55
|
end
|
51
56
|
|
52
|
-
|
57
|
+
private
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
# use the config options from the config file
|
60
|
+
def self.configure_from(env_config)
|
61
|
+
@database_path = env_config["database"] || ":memory:"
|
62
|
+
@adapter = env_config["adapter"] || :active_record
|
63
|
+
@writer = env_config["writer"] || :direct
|
64
|
+
@beanstalk_daemon = env_config["beanstalk_daemon"]
|
65
|
+
@language = env_config["language"]
|
66
|
+
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
# set default config options
|
69
|
+
def self.configure_defaults
|
70
|
+
Rails.env == "test" ? @database_path = ":memory:" : @database_path = "db/xapian_db/#{Rails.env}"
|
71
|
+
@adapter = :active_record
|
72
|
+
@writer = :direct
|
73
|
+
@beanstalk_daemon = nil
|
74
|
+
end
|
70
75
|
|
71
76
|
end
|
72
77
|
end
|
data/lib/xapian_db.rb
CHANGED
@@ -88,14 +88,14 @@ module XapianDb
|
|
88
88
|
# Update an object in the index
|
89
89
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
90
90
|
def self.index(obj)
|
91
|
-
writer = @
|
91
|
+
writer = @block_writer || XapianDb::Config.writer
|
92
92
|
writer.index obj
|
93
93
|
end
|
94
94
|
|
95
95
|
# Remove an object from the index
|
96
96
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
97
97
|
def self.unindex(obj)
|
98
|
-
writer = @
|
98
|
+
writer = @block_writer || XapianDb::Config.writer
|
99
99
|
writer.unindex obj
|
100
100
|
end
|
101
101
|
|
@@ -122,27 +122,47 @@ module XapianDb
|
|
122
122
|
|
123
123
|
# Execute a block as a transaction
|
124
124
|
def self.transaction(&block)
|
125
|
-
|
126
|
-
|
125
|
+
writer = XapianDb::IndexWriters::TransactionalWriter.new
|
126
|
+
execute_block :writer => writer, :error_message => "error in XapianDb transaction block, transaction aborted" do
|
127
|
+
block.call
|
128
|
+
writer.commit_using XapianDb::Config.writer
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Execute a block and do not update the index
|
133
|
+
def self.auto_indexing_disabled(&block)
|
134
|
+
execute_block :writer => XapianDb::IndexWriters::NoOpWriter.new do
|
135
|
+
block.call
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
# execute a block of code with a given writer and handle errors
|
141
|
+
# @param [Hash] opts Options
|
142
|
+
# @option opts [Object] :writer An index writer
|
143
|
+
# @option opts [String] :error_message the error message to log if an error occurs
|
144
|
+
def self.execute_block(opts, &block)
|
145
|
+
@block_writer = opts[:writer]
|
127
146
|
begin
|
128
147
|
block.call
|
129
|
-
@transactional_writer.commit_using XapianDb::Config.writer
|
130
148
|
rescue Exception => ex
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
149
|
+
if opts[:error_message]
|
150
|
+
if defined?(Rails)
|
151
|
+
Rails.logger.error opts[:error_message]
|
152
|
+
else
|
153
|
+
puts opts[:error_message]
|
154
|
+
end
|
136
155
|
end
|
156
|
+
raise
|
137
157
|
ensure
|
138
|
-
# release the
|
139
|
-
@
|
158
|
+
# release the block writer
|
159
|
+
@block_writer = nil
|
140
160
|
end
|
141
161
|
end
|
142
162
|
|
143
163
|
end
|
144
164
|
|
145
|
-
do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb utilities.rb)
|
165
|
+
do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb utilities.rb install_generator.rb)
|
146
166
|
files = Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").reject{|path| do_not_require.include?(File.basename(path))}
|
147
167
|
# Require these first
|
148
168
|
require "#{File.dirname(__FILE__)}/xapian_db/utilities"
|
data/tasks/beanstalk_worker.rake
CHANGED
@@ -11,16 +11,18 @@ require 'yaml'
|
|
11
11
|
|
12
12
|
namespace :xapian_db do
|
13
13
|
|
14
|
-
|
14
|
+
DEPRECATION_WARNING = "beanstalk_worker.rake is deprecated, use script/beanstalk_worker instead"
|
15
|
+
desc DEPRECATION_WARNING
|
15
16
|
task :beanstalk_worker do
|
16
17
|
|
17
18
|
url = XapianDb::Config.beanstalk_daemon_url
|
18
19
|
beanstalk = Beanstalk::Pool.new([url])
|
19
20
|
worker = XapianDb::IndexWriters::BeanstalkWorker.new
|
21
|
+
puts DEPRECATION_WARNING
|
20
22
|
puts "XapianDb beanstalk worker is serving on #{url}..."
|
21
23
|
loop do
|
22
|
-
job = beanstalk.reserve
|
23
24
|
begin
|
25
|
+
job = beanstalk.reserve
|
24
26
|
params = YAML::load job.body
|
25
27
|
Rails.logger.info "XapianDb beanstalk worker: executing task #{params}"
|
26
28
|
task = params.delete :task
|
@@ -28,7 +30,13 @@ namespace :xapian_db do
|
|
28
30
|
rescue Exception => ex
|
29
31
|
Rails.logger.error "XapianDb beanstalk worker: could not process #{job.body} (#{ex})"
|
30
32
|
end
|
31
|
-
|
33
|
+
|
34
|
+
begin
|
35
|
+
job.delete
|
36
|
+
rescue Exception => ex
|
37
|
+
Rails.logger.error "XapianDb beanstalk worker: could delete job #{job.body} (#{ex})"
|
38
|
+
end
|
39
|
+
|
32
40
|
end
|
33
41
|
|
34
42
|
end
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 5
|
8
|
-
-
|
9
|
-
version: 0.5.
|
8
|
+
- 10
|
9
|
+
version: 0.5.10
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Gernot Kogler
|
@@ -14,13 +14,28 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-04-06 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
21
|
+
name: daemons
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 10
|
32
|
+
version: 1.0.10
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
24
39
|
none: false
|
25
40
|
requirements:
|
26
41
|
- - ">="
|
@@ -31,11 +46,11 @@ dependencies:
|
|
31
46
|
- 1
|
32
47
|
version: 2.3.1
|
33
48
|
type: :development
|
34
|
-
version_requirements: *
|
49
|
+
version_requirements: *id002
|
35
50
|
- !ruby/object:Gem::Dependency
|
36
51
|
name: simplecov
|
37
52
|
prerelease: false
|
38
|
-
requirement: &
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
54
|
none: false
|
40
55
|
requirements:
|
41
56
|
- - ">="
|
@@ -46,11 +61,11 @@ dependencies:
|
|
46
61
|
- 7
|
47
62
|
version: 0.3.7
|
48
63
|
type: :development
|
49
|
-
version_requirements: *
|
64
|
+
version_requirements: *id003
|
50
65
|
- !ruby/object:Gem::Dependency
|
51
66
|
name: beanstalk-client
|
52
67
|
prerelease: false
|
53
|
-
requirement: &
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
54
69
|
none: false
|
55
70
|
requirements:
|
56
71
|
- - ">="
|
@@ -61,7 +76,7 @@ dependencies:
|
|
61
76
|
- 0
|
62
77
|
version: 1.1.0
|
63
78
|
type: :development
|
64
|
-
version_requirements: *
|
79
|
+
version_requirements: *id004
|
65
80
|
description: XapianDb is a ruby gem that combines features of nosql databases and fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
|
66
81
|
email: gernot.kogler (at) garaio (dot) com
|
67
82
|
executables: []
|
@@ -71,6 +86,8 @@ extensions:
|
|
71
86
|
extra_rdoc_files: []
|
72
87
|
|
73
88
|
files:
|
89
|
+
- lib/generators/install_generator.rb
|
90
|
+
- lib/generators/templates/beanstalk_worker
|
74
91
|
- lib/xapian_db/adapters/active_record_adapter.rb
|
75
92
|
- lib/xapian_db/adapters/base_adapter.rb
|
76
93
|
- lib/xapian_db/adapters/datamapper_adapter.rb
|
@@ -81,6 +98,7 @@ files:
|
|
81
98
|
- lib/xapian_db/index_writers/beanstalk_worker.rb
|
82
99
|
- lib/xapian_db/index_writers/beanstalk_writer.rb
|
83
100
|
- lib/xapian_db/index_writers/direct_writer.rb
|
101
|
+
- lib/xapian_db/index_writers/no_op_writer.rb
|
84
102
|
- lib/xapian_db/index_writers/transactional_writer.rb
|
85
103
|
- lib/xapian_db/indexer.rb
|
86
104
|
- lib/xapian_db/query_parser.rb
|
@@ -106,8 +124,8 @@ files:
|
|
106
124
|
- lib/xapian_db/utilities.rb
|
107
125
|
- lib/xapian_db.rb
|
108
126
|
- tasks/beanstalk_worker.rake
|
109
|
-
- xapian_source/xapian-bindings-1.2.
|
110
|
-
- xapian_source/xapian-core-1.2.
|
127
|
+
- xapian_source/xapian-bindings-1.2.5.tar.gz
|
128
|
+
- xapian_source/xapian-core-1.2.5.tar.gz
|
111
129
|
- LICENSE
|
112
130
|
- README.rdoc
|
113
131
|
- CHANGELOG.md
|
Binary file
|
Binary file
|