promiscuous 0.91.0 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/promiscuous.rb +1 -1
- data/lib/promiscuous/amqp.rb +1 -1
- data/lib/promiscuous/amqp/fake.rb +0 -3
- data/lib/promiscuous/amqp/file.rb +81 -0
- data/lib/promiscuous/amqp/null.rb +0 -3
- data/lib/promiscuous/cli.rb +35 -25
- data/lib/promiscuous/config.rb +8 -3
- data/lib/promiscuous/error.rb +1 -2
- data/lib/promiscuous/key.rb +1 -12
- data/lib/promiscuous/mongoid.rb +7 -0
- data/lib/promiscuous/publisher/context/base.rb +4 -4
- data/lib/promiscuous/publisher/context/middleware.rb +2 -23
- data/lib/promiscuous/publisher/model/ephemeral.rb +5 -1
- data/lib/promiscuous/publisher/model/mock.rb +9 -7
- data/lib/promiscuous/publisher/model/mongoid.rb +3 -1
- data/lib/promiscuous/publisher/operation.rb +1 -1
- data/lib/promiscuous/publisher/operation/atomic.rb +44 -32
- data/lib/promiscuous/publisher/operation/base.rb +14 -9
- data/lib/promiscuous/publisher/operation/ephemeral.rb +14 -0
- data/lib/promiscuous/publisher/operation/mongoid.rb +4 -12
- data/lib/promiscuous/subscriber/message_processor/base.rb +17 -1
- data/lib/promiscuous/subscriber/message_processor/regular.rb +94 -48
- data/lib/promiscuous/subscriber/model/active_record.rb +25 -0
- data/lib/promiscuous/subscriber/model/base.rb +17 -13
- data/lib/promiscuous/subscriber/model/mongoid.rb +20 -1
- data/lib/promiscuous/subscriber/model/observer.rb +4 -0
- data/lib/promiscuous/subscriber/operation/base.rb +14 -16
- data/lib/promiscuous/subscriber/operation/bootstrap.rb +7 -1
- data/lib/promiscuous/subscriber/operation/regular.rb +6 -0
- data/lib/promiscuous/subscriber/worker.rb +6 -2
- data/lib/promiscuous/subscriber/worker/eventual_destroyer.rb +85 -0
- data/lib/promiscuous/subscriber/worker/message.rb +9 -15
- data/lib/promiscuous/subscriber/worker/message_synchronizer.rb +24 -78
- data/lib/promiscuous/subscriber/worker/runner.rb +6 -2
- data/lib/promiscuous/subscriber/worker/stats.rb +11 -7
- data/lib/promiscuous/version.rb +1 -1
- metadata +66 -63
- data/lib/promiscuous/error/already_processed.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d772f9b9786ef7ee6787030113bf9ec5934717d5
|
4
|
+
data.tar.gz: 163c9cb61d4b359f1e6766effef9baccdfd8c229
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cacc43f226549868f963abbad29e7ba7249a1bbc1c4eb3e0b8014275935ca37e7455a73b48e36d7c0c56906308ab334c104bbf136a7cd2c7345ee976161eead
|
7
|
+
data.tar.gz: 6f59e694ed2c89e2ebe9a6c73995c4b6e4987ee1f43d171f55f3783b9698c4974aff8ef684d22dd8e652956d943081b952f8bb313d492016629b9564a1447727
|
data/lib/promiscuous.rb
CHANGED
@@ -13,7 +13,7 @@ module Promiscuous
|
|
13
13
|
require_for 'rails', 'promiscuous/railtie'
|
14
14
|
require_for 'resque', 'promiscuous/resque'
|
15
15
|
require_for 'sidekiq', 'promiscuous/sidekiq'
|
16
|
-
|
16
|
+
require_for 'mongoid', 'promiscuous/mongoid'
|
17
17
|
|
18
18
|
extend Promiscuous::Autoload
|
19
19
|
autoload :Common, :Publisher, :Subscriber, :Observer, :Worker, :Ephemeral,
|
data/lib/promiscuous/amqp.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
class Promiscuous::AMQP::File
|
2
|
+
def connect
|
3
|
+
end
|
4
|
+
|
5
|
+
def disconnect
|
6
|
+
end
|
7
|
+
|
8
|
+
def connected?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def new_connection(options={})
|
13
|
+
end
|
14
|
+
|
15
|
+
def publish(options={})
|
16
|
+
options[:on_confirm].try(:call)
|
17
|
+
raise NotImplemented
|
18
|
+
end
|
19
|
+
|
20
|
+
module Subscriber
|
21
|
+
attr_accessor :lock, :prefetch_wait, :num_pending
|
22
|
+
|
23
|
+
def subscribe(options={}, &block)
|
24
|
+
file_name, worker_index, num_workers = Promiscuous::Config.subscriber_amqp_url.split(':')
|
25
|
+
|
26
|
+
worker_index = worker_index.to_i
|
27
|
+
num_workers = num_workers.to_i
|
28
|
+
|
29
|
+
file = File.open(file_name, 'r')
|
30
|
+
|
31
|
+
@prefetch = Promiscuous::Config.prefetch
|
32
|
+
@num_pending = 0
|
33
|
+
@lock = Mutex.new
|
34
|
+
@prefetch_wait = ConditionVariable.new
|
35
|
+
|
36
|
+
@thread = Thread.new do
|
37
|
+
file.each_with_index do |line, i|
|
38
|
+
if num_workers > 0
|
39
|
+
next if ((i+worker_index) % num_workers) != 0
|
40
|
+
end
|
41
|
+
|
42
|
+
return if @stop
|
43
|
+
|
44
|
+
@lock.synchronize do
|
45
|
+
@prefetch_wait.wait(@lock) until @num_pending < @prefetch
|
46
|
+
@num_pending += 1
|
47
|
+
end
|
48
|
+
|
49
|
+
block.call(Metadata.new(self), line.chomp)
|
50
|
+
end
|
51
|
+
|
52
|
+
@lock.synchronize do
|
53
|
+
@prefetch_wait.wait(@lock) until @num_pending == 0
|
54
|
+
end
|
55
|
+
|
56
|
+
# will shutdown the CLI gracefully
|
57
|
+
Process.kill("SIGTERM", Process.pid)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def recover
|
62
|
+
end
|
63
|
+
|
64
|
+
def disconnect
|
65
|
+
@stop = true
|
66
|
+
end
|
67
|
+
|
68
|
+
class Metadata
|
69
|
+
def initialize(sub)
|
70
|
+
@sub = sub
|
71
|
+
end
|
72
|
+
|
73
|
+
def ack
|
74
|
+
@sub.lock.synchronize do
|
75
|
+
@sub.num_pending -= 1
|
76
|
+
@sub.prefetch_wait.signal
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/promiscuous/cli.rb
CHANGED
@@ -3,22 +3,28 @@ class Promiscuous::CLI
|
|
3
3
|
|
4
4
|
def trap_debug_signals
|
5
5
|
Signal.trap 'SIGUSR2' do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
print_status
|
6
|
+
# Using a thread because we cannot acquire mutexes in a trap context in
|
7
|
+
# ruby 2.0
|
8
|
+
Thread.new do
|
9
|
+
Thread.list.each do |thread|
|
10
|
+
next if Thread.current == thread
|
11
|
+
|
12
|
+
print_status '----[ Threads ]----' + '-' * (100-19)
|
13
|
+
if thread.backtrace
|
14
|
+
print_status "Thread #{thread} #{thread['label']}"
|
15
|
+
print_status thread.backtrace.join("\n")
|
16
|
+
else
|
17
|
+
print_status "Thread #{thread} #{thread['label']} -- no backtrace"
|
18
|
+
end
|
13
19
|
end
|
14
|
-
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
if @worker && @worker.respond_to?(:message_synchronizer)
|
22
|
+
if blocked_messages = @worker.message_synchronizer.try(:blocked_messages)
|
23
|
+
print_status '----[ Pending Dependencies ]----' + '-' * (100-32)
|
24
|
+
blocked_messages.reverse_each { |msg| print_status msg }
|
25
|
+
end
|
26
|
+
print_status '-' * 100
|
20
27
|
end
|
21
|
-
print_status '-' * 100
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end
|
@@ -26,14 +32,18 @@ class Promiscuous::CLI
|
|
26
32
|
def trap_exit_signals
|
27
33
|
%w(SIGTERM SIGINT).each do |signal|
|
28
34
|
Signal.trap(signal) do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@stop
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
# Using a thread because we cannot acquire mutexes in a trap context in
|
36
|
+
# ruby 2.0
|
37
|
+
Thread.new do
|
38
|
+
print_status "Exiting..."
|
39
|
+
if @stop
|
40
|
+
@worker.try(:show_stop_status)
|
41
|
+
else
|
42
|
+
@stop = true
|
43
|
+
@worker.try(:stop)
|
44
|
+
@worker = nil
|
45
|
+
end
|
46
|
+
end.join
|
37
47
|
end
|
38
48
|
end
|
39
49
|
end
|
@@ -144,12 +154,12 @@ class Promiscuous::CLI
|
|
144
154
|
Promiscuous::Config.no_deps = true
|
145
155
|
end
|
146
156
|
|
147
|
-
opts.on "-
|
148
|
-
|
157
|
+
opts.on "-x", "--ignore-exceptions", "Ignore exceptions and continue to process messages" do
|
158
|
+
Promiscuous::Config.ignore_exceptions = true
|
149
159
|
end
|
150
160
|
|
151
|
-
opts.on "-
|
152
|
-
|
161
|
+
opts.on "-l", "--require FILE", "File to require to load your app. Don't worry about it with rails" do |file|
|
162
|
+
options[:require] = file
|
153
163
|
end
|
154
164
|
|
155
165
|
opts.on "-p", "--prefetch [NUM]", "Number of messages to prefetch" do |prefetch|
|
data/lib/promiscuous/config.rb
CHANGED
@@ -3,9 +3,10 @@ module Promiscuous::Config
|
|
3
3
|
:publisher_amqp_url, :subscriber_amqp_url, :publisher_exchange,
|
4
4
|
:subscriber_exchanges, :queue_name, :queue_options, :redis_url,
|
5
5
|
:redis_urls, :redis_stats_url, :stats_interval,
|
6
|
-
:socket_timeout, :heartbeat, :no_deps, :hash_size,
|
6
|
+
:socket_timeout, :heartbeat, :no_deps, :hash_size,
|
7
7
|
:prefetch, :recovery_timeout, :logger, :subscriber_threads,
|
8
|
-
:version_field, :error_notifier, :recovery_on_boot
|
8
|
+
:version_field, :error_notifier, :recovery_on_boot,
|
9
|
+
:on_stats, :ignore_exceptions, :consistency, :max_retries, :generation
|
9
10
|
|
10
11
|
def self.backend=(value)
|
11
12
|
@@backend = value
|
@@ -53,7 +54,6 @@ module Promiscuous::Config
|
|
53
54
|
self.heartbeat ||= 60
|
54
55
|
self.no_deps ||= false
|
55
56
|
self.hash_size ||= 2**20 # one million keys ~ 200Mb.
|
56
|
-
self.recovery ||= false
|
57
57
|
self.prefetch ||= self.bootstrap ? 10000000 : 1000
|
58
58
|
self.recovery_timeout ||= 10
|
59
59
|
self.logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDERR).tap { |l| l.level = Logger::WARN }
|
@@ -61,6 +61,11 @@ module Promiscuous::Config
|
|
61
61
|
self.error_notifier ||= proc {}
|
62
62
|
self.version_field ||= '_v'
|
63
63
|
self.recovery_on_boot = true if self.recovery_on_boot.nil?
|
64
|
+
self.on_stats ||= proc { |rate, latency| }
|
65
|
+
self.ignore_exceptions ||= false
|
66
|
+
self.consistency ||= :eventual
|
67
|
+
self.max_retries ||= 10
|
68
|
+
self.generation ||= 1
|
64
69
|
end
|
65
70
|
|
66
71
|
def self.configure(&block)
|
data/lib/promiscuous/error.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Promiscuous::Error
|
2
2
|
extend Promiscuous::Autoload
|
3
3
|
autoload :Base, :Connection, :Publisher, :Subscriber, :Recovery,
|
4
|
-
:Dependency, :MissingContext, :
|
5
|
-
:LockUnavailable, :LostLock
|
4
|
+
:Dependency, :MissingContext, :LockUnavailable, :LostLock
|
6
5
|
end
|
data/lib/promiscuous/key.rb
CHANGED
@@ -1,21 +1,10 @@
|
|
1
1
|
class Promiscuous::Key
|
2
|
-
def initialize(role, nodes=[]
|
2
|
+
def initialize(role, nodes=[])
|
3
3
|
@role = role
|
4
4
|
@nodes = nodes
|
5
|
-
@no_join = no_join
|
6
5
|
end
|
7
6
|
|
8
7
|
def join(*nodes)
|
9
|
-
# --- backward compatiblity code ---
|
10
|
-
# TODO remove code
|
11
|
-
if nodes == ['global', nil, nil]
|
12
|
-
return self.class.new(@role, @nodes + nodes, :no_join)
|
13
|
-
end
|
14
|
-
if @no_join
|
15
|
-
return self.class.new(@role, @nodes)
|
16
|
-
end
|
17
|
-
# --- backward compatiblity code ---
|
18
|
-
|
19
8
|
self.class.new(@role, @nodes + nodes)
|
20
9
|
end
|
21
10
|
|
@@ -24,11 +24,11 @@ class Promiscuous::Publisher::Context::Base
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
attr_accessor :name, :read_operations, :extra_dependencies, :
|
27
|
+
attr_accessor :name, :read_operations, :extra_dependencies, :current_user
|
28
28
|
|
29
|
-
def initialize(
|
30
|
-
@name =
|
31
|
-
@
|
29
|
+
def initialize(name=nil, options={})
|
30
|
+
@name = name.try(:to_s) || 'anonymous'
|
31
|
+
@current_user = options[:current_user]
|
32
32
|
@read_operations = []
|
33
33
|
@extra_dependencies = []
|
34
34
|
@transaction_managers = {}
|
@@ -4,12 +4,8 @@ class Promiscuous::Publisher::Context::Middleware < Promiscuous::Publisher::Cont
|
|
4
4
|
|
5
5
|
def process_action(*args)
|
6
6
|
full_name = "#{self.class.controller_path}/#{self.action_name}"
|
7
|
-
|
8
|
-
Promiscuous::Publisher::Context::Middleware.with_context(full_name,
|
9
|
-
end
|
10
|
-
|
11
|
-
def render(*args)
|
12
|
-
Promiscuous::Publisher::Context::Middleware.without_context { super }
|
7
|
+
current_user = self.current_user if self.respond_to?(:current_user)
|
8
|
+
Promiscuous::Publisher::Context::Middleware.with_context(full_name, :current_user => current_user) { super }
|
13
9
|
end
|
14
10
|
end
|
15
11
|
|
@@ -26,23 +22,6 @@ class Promiscuous::Publisher::Context::Middleware < Promiscuous::Publisher::Cont
|
|
26
22
|
Promiscuous.disabled = old_disabled
|
27
23
|
end
|
28
24
|
|
29
|
-
def self.without_context
|
30
|
-
# This is different from the method without_promiscuous in convenience.rb
|
31
|
-
# That's used for render() and things that are *not* supposed to write.
|
32
|
-
# We actually force promiscuous to instrument queries, and make sure that
|
33
|
-
# we don't do any writes we shouldn't.
|
34
|
-
old_disabled, Promiscuous.disabled = Promiscuous.disabled?, false
|
35
|
-
old_current, self.current = self.current, nil
|
36
|
-
yield
|
37
|
-
rescue Exception => e
|
38
|
-
$promiscuous_last_exception = e if e.is_a? Promiscuous::Error::Base
|
39
|
-
pretty_print_exception(e) unless e.is_a? ActionView::MissingTemplate
|
40
|
-
raise e
|
41
|
-
ensure
|
42
|
-
self.current = old_current
|
43
|
-
Promiscuous.disabled = old_disabled
|
44
|
-
end
|
45
|
-
|
46
25
|
def self.pretty_print_exception(e)
|
47
26
|
return if $promiscuous_pretty_print_exception_once == :disable || ENV['RAILS_ENV'] == 'production'
|
48
27
|
return if e.is_a?(SystemExit)
|
@@ -33,13 +33,17 @@ module Promiscuous::Publisher::Model::Ephemeral
|
|
33
33
|
operation = :update unless self.new_record
|
34
34
|
operation = :destroy if self.destroyed
|
35
35
|
|
36
|
-
|
36
|
+
save_operation(operation)
|
37
37
|
|
38
38
|
self.new_record = false
|
39
39
|
true
|
40
40
|
end
|
41
41
|
alias :save! :save
|
42
42
|
|
43
|
+
def save_operation(operation)
|
44
|
+
Promiscuous::Publisher::Operation::Ephemeral.new(:instance => self, :operation => operation).execute
|
45
|
+
end
|
46
|
+
|
43
47
|
def update_attributes(attrs)
|
44
48
|
attrs.each { |attr, value| __send__("#{attr}=", value) }
|
45
49
|
save
|
@@ -22,15 +22,17 @@ module Promiscuous::Publisher::Model::Mock
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
include Promiscuous::Publisher::Model::Ephemeral::PromiscuousMethodsEphemeral
|
25
|
+
def save_operation(operation)
|
26
|
+
payload = nil
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
Promiscuous::Publisher::Context::Middleware.with_context("mocking #{self.class}") do
|
29
|
+
op = Promiscuous::Publisher::Operation::Ephemeral.new(:instance => self, :operation => operation)
|
30
|
+
# TODO FIX the mocks to populate app name, also we need to hook before the
|
31
|
+
# json dump.
|
32
|
+
payload = op.generate_payload
|
33
33
|
end
|
34
|
+
|
35
|
+
Promiscuous::Subscriber::Worker::Message.new(payload).process
|
34
36
|
end
|
35
37
|
|
36
38
|
module ClassMethods
|
@@ -23,7 +23,9 @@ module Promiscuous::Publisher::Model::Mongoid
|
|
23
23
|
|
24
24
|
def sync(options={}, &block)
|
25
25
|
raise "Use promiscuous.sync on the parent instance" if @instance.embedded?
|
26
|
-
|
26
|
+
|
27
|
+
# We can use the ephemeral because both are mongoid and ephemerals are atomic operations.
|
28
|
+
Promiscuous::Publisher::Operation::Ephemeral.new(:instance => @instance, :operation => :update).execute
|
27
29
|
end
|
28
30
|
|
29
31
|
def attribute(attr)
|
@@ -35,10 +35,47 @@ class Promiscuous::Publisher::Operation::Atomic < Promiscuous::Publisher::Operat
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
38
|
+
def do_database_query(query)
|
39
|
+
case operation
|
40
|
+
when :create
|
41
|
+
# We don't stash the version in the document as we can't have races
|
42
|
+
# on the same document.
|
43
|
+
when :update
|
44
|
+
increment_version_in_document
|
45
|
+
# We are now in the possession of an instance that matches the original
|
46
|
+
# selector. We need to make sure the db query will operate on it,
|
47
|
+
# instead of the original selector.
|
48
|
+
use_id_selector(:use_atomic_version_selector => true)
|
49
|
+
# We need to use an atomic versioned selector to make sure that
|
50
|
+
# if we lose the lock for a long period of time, we don't mess up
|
51
|
+
# the record. Perhaps the operation has been recovered a while ago.
|
52
|
+
when :destroy
|
53
|
+
use_id_selector
|
54
|
+
end
|
55
|
+
|
56
|
+
# The driver is responsible to set instance to the appropriate value.
|
57
|
+
query.call_and_remember_result(:instrumented)
|
58
|
+
|
59
|
+
if query.failed?
|
60
|
+
# If we get an network failure, we should retry later.
|
61
|
+
return if recoverable_failure?(query.exception)
|
62
|
+
@instance = nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def yell_about_missing_instance
|
67
|
+
err = "Cannot find document. Database had a dataloss?. Proceeding anyways. #{@recovery_data}"
|
68
|
+
e = Promiscuous::Error::Recovery.new(err)
|
69
|
+
Promiscuous.warn "[recovery] #{e}"
|
70
|
+
Promiscuous::Config.error_notifier.call(e)
|
71
|
+
end
|
40
72
|
|
41
|
-
|
73
|
+
def execute_instrumented(query)
|
74
|
+
if recovering?
|
75
|
+
# The DB died or something. We cannot find our instance any more :(
|
76
|
+
# this is a problem, but we need to publish.
|
77
|
+
yell_about_missing_instance if @instance.nil?
|
78
|
+
else
|
42
79
|
generate_read_dependencies
|
43
80
|
acquire_op_lock
|
44
81
|
|
@@ -75,32 +112,7 @@ class Promiscuous::Publisher::Operation::Atomic < Promiscuous::Publisher::Operat
|
|
75
112
|
# documents are missing on our side to be able to resend the destroy
|
76
113
|
# message.
|
77
114
|
|
78
|
-
|
79
|
-
when :create
|
80
|
-
# We don't stash the version in the document as we can't have races
|
81
|
-
# on the same document.
|
82
|
-
when :update
|
83
|
-
stash_version_in_document(@committed_write_deps.first.version)
|
84
|
-
# We are now in the possession of an instance that matches the original
|
85
|
-
# selector. We need to make sure the db query will operate on it,
|
86
|
-
# instead of the original selector.
|
87
|
-
use_id_selector(:use_atomic_version_selector => true)
|
88
|
-
# We need to use an atomic versioned selector to make sure that
|
89
|
-
# if we lose the lock for a long period of time, we don't mess up
|
90
|
-
# the record. Perhaps the operation has been recovered a while ago.
|
91
|
-
when :destroy
|
92
|
-
use_id_selector
|
93
|
-
end
|
94
|
-
|
95
|
-
# The driver is responsible to set instance to the appropriate value.
|
96
|
-
query.call_and_remember_result(:instrumented)
|
97
|
-
|
98
|
-
if query.failed?
|
99
|
-
# If we get an network failure, we should retry later.
|
100
|
-
return if recoverable_failure?(query.exception)
|
101
|
-
@instance = nil
|
102
|
-
end
|
103
|
-
|
115
|
+
do_database_query(query) unless @instance.nil?
|
104
116
|
# We take a timestamp right after the write is performed because latency
|
105
117
|
# measurements are performed on the subscriber.
|
106
118
|
record_timestamp
|
@@ -141,6 +153,7 @@ class Promiscuous::Publisher::Operation::Atomic < Promiscuous::Publisher::Operat
|
|
141
153
|
def fetch_instance
|
142
154
|
# This method is overridden to use the original query selector.
|
143
155
|
# Should return nil if the instance is not found.
|
156
|
+
@instance.reload if @instance.respond_to?(:reload)
|
144
157
|
@instance
|
145
158
|
end
|
146
159
|
|
@@ -148,9 +161,8 @@ class Promiscuous::Publisher::Operation::Atomic < Promiscuous::Publisher::Operat
|
|
148
161
|
@instance = fetch_instance
|
149
162
|
end
|
150
163
|
|
151
|
-
def
|
152
|
-
# Overridden to
|
153
|
-
# instance[Promiscuous::Config.version_field] = version
|
164
|
+
def increment_version_in_document
|
165
|
+
# Overridden to increment version field in the query
|
154
166
|
end
|
155
167
|
|
156
168
|
def use_id_selector(options={})
|