promiscuous 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/promiscuous +10 -0
- data/lib/promiscuous/cli.rb +159 -0
- data/lib/promiscuous/common/worker.rb +1 -1
- data/lib/promiscuous/railtie.rb +0 -2
- data/lib/promiscuous/subscriber/mongoid/versioning.rb +1 -1
- data/lib/promiscuous/version.rb +1 -1
- data/lib/promiscuous/worker.rb +4 -4
- metadata +9 -7
- data/lib/promiscuous/railtie/replicate.rake +0 -87
data/bin/promiscuous
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'promiscuous'
|
2
|
+
|
3
|
+
class Promiscuous::CLI
|
4
|
+
def replicate(config_options={}, &block)
|
5
|
+
require 'eventmachine'
|
6
|
+
require 'em-synchrony'
|
7
|
+
|
8
|
+
EM.synchrony do
|
9
|
+
trap_signals
|
10
|
+
Promiscuous::Loader.load_descriptors if defined?(Rails)
|
11
|
+
force_backend :rubyamqp
|
12
|
+
block.call
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def force_backend(backend)
|
17
|
+
Promiscuous::AMQP.disconnect
|
18
|
+
Promiscuous::Config.backend = backend
|
19
|
+
Promiscuous::AMQP.connect
|
20
|
+
end
|
21
|
+
|
22
|
+
def trap_signals
|
23
|
+
%w(SIGTERM SIGINT).each do |signal|
|
24
|
+
Signal.trap(signal) do
|
25
|
+
print_status "Exiting..."
|
26
|
+
Promiscuous::Worker.stop
|
27
|
+
EM.stop
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def publish(options={})
|
33
|
+
replicate do
|
34
|
+
Promiscuous::Worker.replicate(options)
|
35
|
+
print_status "Replicating with #{Promiscuous::Publisher::Mongoid::Defer.klasses.count} publishers"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def subscribe(options={})
|
40
|
+
replicate do
|
41
|
+
Promiscuous::Worker.replicate(options)
|
42
|
+
print_status "Replicating with #{Promiscuous::Subscriber::AMQP.subscribers.count} subscribers"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def publish_sync(options={})
|
47
|
+
print_status "Replicating #{options[:criteria]}..."
|
48
|
+
criteria = eval(options[:criteria])
|
49
|
+
|
50
|
+
bar = ProgressBar.create(:format => '%t |%b>%i| %c/%C %e', :title => 'Publishing', :total => criteria.count)
|
51
|
+
criteria.each do |doc|
|
52
|
+
doc.promiscuous_sync(options)
|
53
|
+
bar.increment
|
54
|
+
end
|
55
|
+
|
56
|
+
print_status "Done. You may switch your subscriber worker back to regular mode, and delete the sync queues"
|
57
|
+
end
|
58
|
+
|
59
|
+
def subscribe_sync(options={})
|
60
|
+
replicate do
|
61
|
+
# Create the regular queue if needed, so we don't lose messages.
|
62
|
+
Promiscuous::AMQP.open_queue(Promiscuous::Subscriber::Worker.new.queue_bindings)
|
63
|
+
|
64
|
+
print_status "WARNING: --- SYNC MODE ----"
|
65
|
+
print_status "WARNING: Make sure you are not running the regular subscriber worker (it's racy)"
|
66
|
+
print_status "WARNING: --- SYNC MODE ----"
|
67
|
+
Promiscuous::Worker.replicate(options)
|
68
|
+
print_status "Replicating with #{Promiscuous::Subscriber::AMQP.subscribers.count} subscribers"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_args(args)
|
73
|
+
options = {}
|
74
|
+
|
75
|
+
parser = OptionParser.new do |opts|
|
76
|
+
opts.banner = "Usage: promiscuous [options] action"
|
77
|
+
|
78
|
+
opts.separator ""
|
79
|
+
opts.separator "Actions:"
|
80
|
+
opts.separator " publish"
|
81
|
+
opts.separator " subscribe"
|
82
|
+
opts.separator ""
|
83
|
+
opts.separator "Options:"
|
84
|
+
|
85
|
+
opts.on "-s", "--sync", "Use a separate queue for sychronizing databases" do
|
86
|
+
options[:personality] = :sync
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on "-c", "--criteria CRITERIA", "Published criteria in sync mode (often a model)" do |criteria|
|
90
|
+
options[:criteria] = criteria
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on "-b", "--bareback", "Bareback mode aka continue on error. Use with extreme caution" do
|
94
|
+
options[:bareback] = true
|
95
|
+
end
|
96
|
+
|
97
|
+
opts.on "-r", "--require FILE", "File to require to load your app. Don't worry about it with rails" do |file|
|
98
|
+
options[:require] = file
|
99
|
+
end
|
100
|
+
|
101
|
+
opts.on("-h", "--help", "Show this message") do
|
102
|
+
puts opts
|
103
|
+
exit
|
104
|
+
end
|
105
|
+
|
106
|
+
opts.on("-V", "--version", "Show version") do
|
107
|
+
puts "Promiscuous #{Promiscuous::VERSION}"
|
108
|
+
puts "License MIT"
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
args = args.dup
|
114
|
+
parser.parse!(args)
|
115
|
+
|
116
|
+
options[:action] = args.shift.try(:to_sym)
|
117
|
+
raise "Please specify an action (publish or subscribe)" unless options[:action].in? [:publish, :subscribe]
|
118
|
+
|
119
|
+
if options[:action] == :publish && options[:personality] == :sync
|
120
|
+
raise "Please specify a criteria" unless options[:criteria]
|
121
|
+
else
|
122
|
+
raise "Why are you specifying a criteria?" if options[:criteria]
|
123
|
+
end
|
124
|
+
|
125
|
+
options
|
126
|
+
end
|
127
|
+
|
128
|
+
def load_app(options={})
|
129
|
+
if options[:require]
|
130
|
+
require options[:require]
|
131
|
+
else
|
132
|
+
require 'rails'
|
133
|
+
require File.expand_path("./config/environment.rb")
|
134
|
+
::Rails.application.eager_load!
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def run
|
139
|
+
options = parse_args(ARGV)
|
140
|
+
load_app(options)
|
141
|
+
maybe_warn_bareback(options)
|
142
|
+
|
143
|
+
# calls publish, publish_sync, subscribe, subscribe_sync
|
144
|
+
__send__([options[:action], options[:personality]].compact.join('_'), options)
|
145
|
+
end
|
146
|
+
|
147
|
+
def maybe_warn_bareback(options)
|
148
|
+
if options[:bareback]
|
149
|
+
print_status "WARNING: --- BAREBACK MODE ----"
|
150
|
+
print_status "WARNING: You are replicating without protection, you can get corrupted in no time"
|
151
|
+
print_status "WARNING: --- BAREBACK MODE ----"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def print_status(msg)
|
156
|
+
Promiscuous.info msg
|
157
|
+
$stderr.puts msg
|
158
|
+
end
|
159
|
+
end
|
data/lib/promiscuous/railtie.rb
CHANGED
@@ -6,7 +6,7 @@ module Promiscuous::Subscriber::Mongoid::Versioning
|
|
6
6
|
|
7
7
|
def atomic_selector
|
8
8
|
if use_atomic_promiscuous_selector
|
9
|
-
super.merge({ '$or' => [{'_psv' => { '$
|
9
|
+
super.merge({ '$or' => [{'_psv' => { '$lte' => self._psv }},
|
10
10
|
{'_psv' => { '$exists' => false }}]})
|
11
11
|
else
|
12
12
|
super
|
data/lib/promiscuous/version.rb
CHANGED
data/lib/promiscuous/worker.rb
CHANGED
@@ -3,11 +3,11 @@ module Promiscuous::Worker
|
|
3
3
|
self.workers = []
|
4
4
|
|
5
5
|
def self.replicate(options={})
|
6
|
-
|
7
|
-
|
6
|
+
options[:action] ||= [:publish, :subscribe]
|
7
|
+
actions = [options[:action]].flatten
|
8
8
|
|
9
|
-
self.workers << Promiscuous::Publisher::Worker.new(options)
|
10
|
-
self.workers << Promiscuous::Subscriber::Worker.new(options) if subscribe
|
9
|
+
self.workers << Promiscuous::Publisher::Worker.new(options) if :publish.in? actions
|
10
|
+
self.workers << Promiscuous::Subscriber::Worker.new(options) if :subscribe.in? actions
|
11
11
|
self.workers.each { |w| w.replicate }
|
12
12
|
end
|
13
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: promiscuous
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-12-
|
13
|
+
date: 2012-12-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -112,13 +112,14 @@ description: Replicate your Mongoid/ActiveRecord models across your applications
|
|
112
112
|
email:
|
113
113
|
- nicolas@viennot.biz
|
114
114
|
- kareem@doubleonemedia.com
|
115
|
-
executables:
|
115
|
+
executables:
|
116
|
+
- promiscuous
|
116
117
|
extensions: []
|
117
118
|
extra_rdoc_files: []
|
118
119
|
files:
|
119
120
|
- lib/promiscuous/amqp/null.rb
|
120
|
-
- lib/promiscuous/amqp/bunny.rb
|
121
121
|
- lib/promiscuous/amqp/rubyamqp.rb
|
122
|
+
- lib/promiscuous/amqp/bunny.rb
|
122
123
|
- lib/promiscuous/common/lint.rb
|
123
124
|
- lib/promiscuous/common/lint/base.rb
|
124
125
|
- lib/promiscuous/common/class_helpers.rb
|
@@ -148,8 +149,6 @@ files:
|
|
148
149
|
- lib/promiscuous/publisher/ephemeral.rb
|
149
150
|
- lib/promiscuous/publisher/mongoid.rb
|
150
151
|
- lib/promiscuous/publisher/worker.rb
|
151
|
-
- lib/promiscuous/railtie.rb
|
152
|
-
- lib/promiscuous/railtie/replicate.rake
|
153
152
|
- lib/promiscuous/subscriber/active_record.rb
|
154
153
|
- lib/promiscuous/subscriber/envelope.rb
|
155
154
|
- lib/promiscuous/subscriber/error.rb
|
@@ -176,12 +175,15 @@ files:
|
|
176
175
|
- lib/promiscuous/common.rb
|
177
176
|
- lib/promiscuous/config.rb
|
178
177
|
- lib/promiscuous/amqp.rb
|
179
|
-
- lib/promiscuous/worker.rb
|
180
178
|
- lib/promiscuous/ephemeral.rb
|
181
179
|
- lib/promiscuous/subscriber.rb
|
182
180
|
- lib/promiscuous/publisher.rb
|
181
|
+
- lib/promiscuous/cli.rb
|
182
|
+
- lib/promiscuous/railtie.rb
|
183
|
+
- lib/promiscuous/worker.rb
|
183
184
|
- lib/promiscuous/version.rb
|
184
185
|
- lib/promiscuous.rb
|
186
|
+
- bin/promiscuous
|
185
187
|
- README.md
|
186
188
|
homepage: http://github.com/crowdtap/promiscuous
|
187
189
|
licenses: []
|
@@ -1,87 +0,0 @@
|
|
1
|
-
namespace :promiscuous do
|
2
|
-
# Note These rake tasks can be loaded without Rails
|
3
|
-
|
4
|
-
def trap_signals
|
5
|
-
%w(SIGTERM SIGINT).each do |signal|
|
6
|
-
Signal.trap(signal) do
|
7
|
-
Promiscuous.info "Exiting..."
|
8
|
-
Promiscuous::Worker.stop
|
9
|
-
EM.stop
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def print_status(msg)
|
15
|
-
Promiscuous.info msg
|
16
|
-
$stderr.puts msg
|
17
|
-
end
|
18
|
-
|
19
|
-
def force_backend(backend)
|
20
|
-
Promiscuous::AMQP.disconnect
|
21
|
-
Promiscuous::Config.backend = backend
|
22
|
-
Promiscuous::AMQP.connect
|
23
|
-
end
|
24
|
-
|
25
|
-
def replicate(config_options={}, &block)
|
26
|
-
require 'eventmachine'
|
27
|
-
require 'em-synchrony'
|
28
|
-
|
29
|
-
EM.synchrony do
|
30
|
-
trap_signals
|
31
|
-
Promiscuous::Loader.load_descriptors if defined?(Rails)
|
32
|
-
force_backend :rubyamqp
|
33
|
-
block.call
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
desc 'Run the publisher worker'
|
38
|
-
task :publish => :environment do
|
39
|
-
replicate do
|
40
|
-
Promiscuous::Worker.replicate :only => :publish
|
41
|
-
print_status "Replicating with #{Promiscuous::Publisher::Mongoid::Defer.klasses.count} publishers"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
desc 'Run the subscriber worker'
|
46
|
-
task :subscribe => :environment do
|
47
|
-
replicate do
|
48
|
-
Promiscuous::Worker.replicate :only => :subscribe
|
49
|
-
print_status "Replicating with #{Promiscuous::Subscriber::AMQP.subscribers.count} subscribers"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
namespace :synchronized do
|
54
|
-
desc 'Synchronize a collection'
|
55
|
-
task :publish, [:criteria] => :environment do |t, args|
|
56
|
-
raise "Usage: rake promiscuous:synchronized:publish[Model]" unless args.criteria
|
57
|
-
|
58
|
-
criteria = eval(args.criteria)
|
59
|
-
count = criteria.count
|
60
|
-
print_status "Replicating #{args.criteria}..."
|
61
|
-
|
62
|
-
bar = ProgressBar.create(:format => '%t |%b>%i| %c/%C %e',
|
63
|
-
:title => 'Publishing',
|
64
|
-
:total => count)
|
65
|
-
criteria.each do |doc|
|
66
|
-
doc.promiscuous_sync :personality => :sync
|
67
|
-
bar.increment
|
68
|
-
end
|
69
|
-
|
70
|
-
print_status "Done. You may switch your subscriber worker back to regular mode, and delete the sync queues"
|
71
|
-
end
|
72
|
-
|
73
|
-
desc 'Subscribe to a collection synchronization'
|
74
|
-
task :subscribe => :environment do |t|
|
75
|
-
replicate do
|
76
|
-
# Create the regular queue if needed, so we don't lose messages.
|
77
|
-
Promiscuous::AMQP.open_queue(Promiscuous::Subscriber::Worker.new.queue_bindings)
|
78
|
-
|
79
|
-
print_status "WARNING: --- SYNC MODE ----"
|
80
|
-
print_status "WARNING: Make sure you are not running the regular subscriber worker (it's racy)"
|
81
|
-
print_status "WARNING: --- SYNC MODE ----"
|
82
|
-
Promiscuous::Worker.replicate :personality => :sync, :only => :subscribe
|
83
|
-
print_status "Replicating with #{Promiscuous::Subscriber::AMQP.subscribers.count} subscribers"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|