Skip to content
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

Non-blocking Redis calls: add an async worker #92

Merged
merged 11 commits into from
Apr 23, 2019
Merged

Conversation

davidor
Copy link
Contributor

@davidor davidor commented Mar 19, 2019

This PR continues the work started in #77

It adds a Worker class that processes jobs using the async storage introduced in #77

Notice that the base branch of this PR is the integration branch async, not master.

Note: CircleCI fails because the CI image contains a ruby version that is not compatible with this feature (async lib requires ruby >= 2.2.7).

@davidor
Copy link
Contributor Author

davidor commented Apr 10, 2019

Rebased on top of the async branch after merging #93

:max_pending_jobs,
# Seconds to wait before fetching more jobs when the number of jobs
# in memory has reached max_pending_jobs.
:seconds_before_fetching_more
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throttling?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's worth it to add an extra dependency for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant the rename it to throttling

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
I misunderstood you 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this, but in the end I decided to keep the original name because I think it's more explicit. Throttling is more generic, depending on the algorithm used it can refer to number of requests per unit of time, that plus a burst rate, etc.

private_constant :DEFAULT_WAIT_BEFORE_FETCHING_MORE_JOBS

class RedisConnectionError < RuntimeError
def initialize(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If what it is doing is only super, do you need it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right 👍

else
raise e
end
rescue => e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rescue and raise the exception is not needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

encoded_job[0].sub!('queue:', '')
Resque::Job.new(encoded_job[0],
Yajl::Parser.parse(encoded_job[1], check_utf8: false))
rescue Exception => e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to rescue all Exception here? Even signals?
If so please add a note.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signals are trapped in a different file.

If something happens while decoding the job we do not want the program to exit, and we want to log what happened, so I think that the current solution is OK. There's a brief explanation just below this line.


# redis-rb accepts a Hash as last arg that can contain :timeout.
if call_args.last.is_a? Hash
timeout = call_args.last[:timeout]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
timeout = call_args.last[:timeout]
timeout = call_args.pop[:timeout]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

# redis-rb accepts a Hash as last arg that can contain :timeout.
if call_args.last.is_a? Hash
timeout = call_args.last[:timeout]
call_args.pop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
call_args.pop

I forgot to add this method in previous PRs.

This method needs to be treated a bit differently because redis-rb
accepts a hash that contains a timeout. We need to get that timeout and
simply send it as the last param of the list.
And transform Worker into a module that contains common methods for
other workers.
While at it, remove TODO about stubbing the timeout that no longer
applies.
@davidor
Copy link
Contributor Author

davidor commented Apr 11, 2019

I addressed your comments @hallelujah . Thanks for the review.

@davidor davidor merged commit 18b06c7 into async Apr 23, 2019
@bors bors bot deleted the async-redis-worker branch April 23, 2019 10:21
bors bot added a commit that referenced this pull request Sep 30, 2019
96: Non-blocking redis calls using redis-async lib r=unleashed a=davidor

This is an integration branch. It contains: #77 , #86 , #92 , #93 .
~It cannot be merged yet. We need to drop support for Ruby < 2.2.7 first.~

Co-authored-by: David Ortiz <z.david.ortiz@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants