Class: Tengine::Core::Event
- Inherits:
-
Object
- Object
- Tengine::Core::Event
- Includes:
- Mongoid::Document, Mongoid::Timestamps, CollectionAccessible, SelectableAttr, Validation
- Defined in:
- lib/tengine/core/event.rb
Defined Under Namespace
Classes: Finder
Constant Summary
Constants included from Validation
Validation::BASE_NAME, Validation::EVENT_TYPE_NAME, Validation::RESOURCE_IDENTIFIER, Validation::RESOURCE_IDENTIFIER_PROTOCOL_FORMAT
Instance Attribute Summary collapse
-
#kernel ⇒ Object
tengined実行時に処理しているカーネルのインスタンスを保持します.
Class Method Summary collapse
-
.find_or_create_then_update_with_block(condition, retry_max = 60, wtimeout = 10240) {|event| ... } ⇒ Tengine::Core::Event
The event in question if update succeeded, false if retry_max reached, or nil if the block exited with false.
Instance Method Summary collapse
Instance Attribute Details
#kernel ⇒ Object
tengined実行時に処理しているカーネルのインスタンスを保持します
57 58 59 |
# File 'lib/tengine/core/event.rb', line 57 def kernel @kernel end |
Class Method Details
.find_or_create_then_update_with_block(condition, retry_max = 60, wtimeout = 10240) {|event| ... } ⇒ Tengine::Core::Event
Returns The event in question if update succeeded, false if retry_max reached, or nil if the block exited with false.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/tengine/core/event.rb', line 76 def self.find_or_create_then_update_with_block condition, retry_max = 60, wtimeout = 10240 # * とある条件を満たすイベントがあれば、それを上書きしたい。 # * なければ、新規作成したい。 # * でもアトミックにやりたい。 # * ないとおもって新規作成しようとしたら裏でイベントが生えていたら、上書きモードでやり直したい。 # * あるとおもって上書きしようとしたら裏でイベントが消えていたら、新規作成モードでやり直したい。 # * という要求をできるだけ高速に処理したい。 the_event = nil retries = -1 results = nil safemode = Tengine::Core::SafeUpdatable.safemode(collection, wtimeout) while true do return false if retries >= retry_max # retryしすぎ retries += 1 # あればとってくる if the_event and not the_event.new_record? the_event.reload else the_event = where(condition).first || new(condition) end return nil if not yield(the_event) # ユザーによる意図的な中断 hash = the_event.as_document.dup # <- dup ? hash.delete "_id" hash['lock_version'] = the_event.lock_version + 1 hash['created_at'] ||= Time.at(Time.now.to_i) hash['updated_at'] = Time.at(Time.now.to_i) results = nil begin # Can't, no results returned... # results = with(safe: safemode).where( # key: the_event.key, lock_version: the_event.lock_version # ).update( # "$set" => hash, # flags: [ :upsert ] # ) mongo_session.with(safe: safemode) do |ss| col = ss[collection.name] results = ss.context.update( col.database.name, col.name, { key: the_event.key, lock_version: the_event.lock_version }, { "$set" => hash }, flags: [ :upsert ] ) end rescue Moped::Errors::OperationFailure => e # upsert = trueだがindexのunique制約があるので重複したkeyは # 作成不可、lock_versionの更新失敗はこちらに来る。これは意 # 図した動作なのでraiseしない。 Tengine.logger.debug "retrying due to mongodb error #{e}" # lock_versionが存在しない可能性(そのような古いDBを引きずっている等) mongo_session.with(safe: safemode) do |ss| col = ss[collection.name] results = ss.context.update( col.database.name, col.name, { "$query" => { key: the_event.key, lock_version: { "$exists" => false} } }, { "$set" => { lock_version: -(2**63) } }, ) end # again else if results["error"] raise Moped::Errors::OperationFailure, results["error"] elsif results["upserted"] # *hack* _idを消してupsertしたので、このとき_idは新しくなっている the_event._id = results["upserted"] the_event.reload return the_event else the_event.reload return the_event end end end rescue Exception p $! end |
Instance Method Details
#to_hash ⇒ Object
59 60 61 62 63 |
# File 'lib/tengine/core/event.rb', line 59 def to_hash ret = attributes.dup # <- dup ? ret.delete "_id" ret end |