@@ -52,7 +52,6 @@ def enqueue_in_transaction(
5252 max_bytes : SolidObjects . configuration . max_payload_bytes
5353 )
5454 instance = find_or_create_instance ( reference , actor_class )
55- instance . lock!
5655
5756 existing = find_idempotent_message ( instance , idempotency_key )
5857 if existing
@@ -108,13 +107,23 @@ def with_instance_retry
108107
109108 # @rbs (Reference, Class) -> Instance
110109 def find_or_create_instance ( reference , actor_class )
111- Instance . create_or_find_by! (
112- actor_type : reference . actor_type ,
113- actor_id : reference . actor_id
114- ) do | instance |
115- instance . state = { }
116- instance . state_version = actor_class . state_version
110+ identity = { actor_type : reference . actor_type , actor_id : reference . actor_id }
111+ identifier = Instance . where ( identity ) . pick ( :id )
112+ return lock_instance! ( identifier ) if identifier
113+
114+ Instance . transaction ( requires_new : true ) do
115+ Instance . create! ( ** identity , state : { } , state_version : actor_class . state_version )
117116 end
117+ rescue ActiveRecord ::RecordNotUnique
118+ lock_instance! ( database_adapter . share_locked ( Instance . where ( identity ) ) . pick ( :id ) )
119+ end
120+
121+ # @rbs (Integer?) -> Instance
122+ def lock_instance! ( identifier )
123+ instance = identifier && Instance . lock . find_by ( id : identifier )
124+ return instance if instance
125+
126+ raise ActiveRecord ::RecordNotFound , "actor instance disappeared while enqueueing"
118127 end
119128
120129 # @rbs (Instance, String?) -> Message?
0 commit comments