diff --git a/lib/crono_trigger/schedulable.rb b/lib/crono_trigger/schedulable.rb index 7fbb404..c0b6a7b 100644 --- a/lib/crono_trigger/schedulable.rb +++ b/lib/crono_trigger/schedulable.rb @@ -223,7 +223,11 @@ def crono_trigger_lock!(**attributes) crono_trigger_column_name(:locked_by) => CronoTrigger.config.worker_id }.merge(attributes) merge_updated_at_for_crono_trigger!(attributes) - update_columns(attributes) + if new_record? + self.attributes = attributes + else + update_columns(attributes) + end end def crono_trigger_unlock! @@ -269,6 +273,7 @@ def crono_trigger_column_name(name) def execute_now crono_trigger_lock!(next_execute_at: Time.now) + save! if new_record? do_execute end diff --git a/spec/crono_trigger/schedulable_spec.rb b/spec/crono_trigger/schedulable_spec.rb index 62b19d2..451bfdc 100644 --- a/spec/crono_trigger/schedulable_spec.rb +++ b/spec/crono_trigger/schedulable_spec.rb @@ -51,6 +51,11 @@ started_at: Time.current.since(2.day), ).tap(&:activate_schedule!) end + let(:new_notification) do + Notification.new( + started_at: Time.current, + ) + end describe "before_create callback" do it "calculate_next_execute_at" do @@ -518,6 +523,14 @@ def notification1.execute notification1.crono_trigger_lock!(next_execute_at: next_execute_at) expect(notification1.next_execute_at).to eq(next_execute_at) end + + it "lock even if unpersisted" do + expect(new_notification.locking?).to be_falsey + expect(new_notification.new_record?).to be_truthy + new_notification.crono_trigger_lock! + expect(new_notification.locking?).to be_truthy + expect(new_notification.new_record?).to be_truthy + end end describe "#assume_executing?" do @@ -603,5 +616,27 @@ def notification1.execute end end end + + it "execute and save unpersisted model" do + Timecop.freeze(Time.utc(2017, 6, 18, 1, 15)) do + aggregate_failures do + expect(CronoTrigger::Models::Execution.count).to eq(0) + expect(Notification.results).to be_empty + expect(new_notification).to receive(:after) + + expect { + new_notification.execute_now + }.to change { new_notification.execute_callback }.from(nil).to(:before) + + expect(new_notification.persisted?).to be_truthy + expect(new_notification.next_execute_at).to be_nil + expect(new_notification.last_executed_at).to eq(Time.utc(2017, 6, 18, 1, 15)) + expect(new_notification.execute_lock).to eq(0) + expect(Notification.results).to eq({new_notification.id => "executed"}) + expect(CronoTrigger::Models::Execution.count).to eq(1) + expect(CronoTrigger::Models::Execution.last.status).to eq("completed") + end + end + end end end