-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
workaround: lock ttl/expiration #20
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
Gem::Specification.new do |s| | ||
s.name = 'fleiss' | ||
s.version = '0.4.4' | ||
s.version = '0.4.5' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No incompatible changes. This is a new, optional feature to be explicitly opted-in by setting |
||
s.authors = ['Black Square Media Ltd'] | ||
s.email = ['[email protected]'] | ||
s.summary = %(Minimialist background jobs backed by ActiveJob and ActiveRecord.) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ class ActiveRecord | |
module Concern | ||
extend ActiveSupport::Concern | ||
|
||
DEFAULT_LOCK_TTL = ENV['FLEISS_LOCK_TTL']&.to_i # seconds | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No dynamic / official config (per-worker or so). Considering this a tweak (even hack). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, so now I see it, I don't like this. Let's add a proper heartbeart instead. How about:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find suggested solution viable but I don't like it too much (still sound workaround-ish):
I tend to implement second option (one heartbeat thread per worker). UPD: looks like https://www.rubydoc.info/gems/concurrent-ruby/Concurrent/TimerTask is the thing for it. UPD2: actually, it cannot be one per worker, but like one per pooled thread because job "owner" is based on thread ID... How much deeper is the rabbit hole? :) Btw, migrations are solved by |
||
|
||
included do | ||
scope :in_queue, ->(qs) { where(queue_name: Array.wrap(qs)) } | ||
scope :finished, -> { where.not(finished_at: nil) } | ||
|
@@ -14,6 +16,15 @@ module Concern | |
scope :started, -> { where(arel_table[:started_at].not_eq(nil)) } | ||
scope :not_started, -> { where(arel_table[:started_at].eq(nil)) } | ||
scope :scheduled, ->(now = Time.zone.now) { where(arel_table[:scheduled_at].gt(now)) } | ||
|
||
scope :lock_expired, lambda {|now = Time.zone.now, lock_ttl = DEFAULT_LOCK_TTL| | ||
if lock_ttl | ||
min_started_at = now - (1.1 * lock_ttl) # 10% threshold | ||
where(finished_at: nil).where(arel_table[:started_at].lt(min_started_at)) # not yet finished and started at quite a while ago | ||
else | ||
none # do nothing unless explicitly configured | ||
end | ||
mxmCherry marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
end | ||
|
||
module ClassMethods | ||
|
@@ -26,12 +37,14 @@ def wrap_perform(&block) | |
|
||
# @return [ActiveRecord::Relation] pending scope | ||
def pending(now = Time.zone.now) | ||
not_finished | ||
.not_expired(now) | ||
.not_started | ||
.where(arel_table[:scheduled_at].lteq(now)) | ||
.order(priority: :desc) | ||
.order(scheduled_at: :asc) | ||
pending = not_finished | ||
.not_expired(now) | ||
.not_started | ||
.where(arel_table[:scheduled_at].lteq(now)) | ||
.order(priority: :desc) | ||
.order(scheduled_at: :asc) | ||
|
||
pending.or(lock_expired(now, DEFAULT_LOCK_TTL)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's not right. if something is e.g. finished or expired, you don't want to include it!! not_finished
.not_exipred
.where(arel_table[:scheduled_at].lteq(now))
.merge(not_started(now).or(lock_expired(now))
.order(priority: :desc, scheduled_at: :asc) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤦 |
||
end | ||
|
||
# @return [ActiveRecord::Relation] in-progress scope | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better English suggestions are welcome ^^