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

allow batch enqueueing of jobs using Redis Pipelining #1

Closed
wants to merge 3 commits into from

Conversation

jack-kerouac
Copy link

@jack-kerouac jack-kerouac commented Dec 19, 2018

This change allows enqueueing a list of jobs with higher performance than one-by-one invoking the existing client.enqueue() method. It therefore uses Redis Pipelining: https://redis.io/topics/pipelining.

I decided against supporting splitting the list of jobs into chunks of e.g. 10,000 jobs, which is recommended by Redis ('Important Note' at https://redis.io/topics/pipelining#redis-pipelining). I mentioned this in the JavaDoc and left it to the client of this method to keep the library simple. Some clients might want to ignore this and I wanted to leave it up to the user.

This change also includes a bit of refactoring of the validate methods to be able to validate the queue name parameter independently of a job parameter.

Closes gresrun#123

@jack-kerouac
Copy link
Author

@maciejp: On top of yesterday's work, I added some more JavaDocs, created an ArrayList with given capacity, mentioned the change in the README, and refactored some of the validate methods.

This is a PR to our own master branch. But I would when you are fine with this open the exact same PR to the original library.

Copy link

@maciejp maciejp left a comment

Choose a reason for hiding this comment

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

all good, just one minor thing with the NPE if I'm not mistaken.
the refactoring I mentioned is purely optional and I'm actually not sure if modifying the test behaviour (replacing the one-by-one enqueuing with batch enqueuing for all lists) is a good idea.

@@ -38,7 +42,7 @@

/**
* Constructor.
*
Copy link

Choose a reason for hiding this comment

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

unnecessary change (in a few places below as well)

* @throws Exception
* in case something goes wrong
*/
protected abstract void doBatchEnqueue(String queue, List<String> msg) throws Exception;
Copy link

Choose a reason for hiding this comment

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

msg -> msgs ? (plural)

@@ -157,13 +195,13 @@ public boolean acquireLock(final String lockName, final String lockHolder, final
* @throws Exception
* in case something goes wrong
*/
protected abstract boolean doAcquireLock(final String lockName, final String lockHolder,
protected abstract boolean doAcquireLock(final String lockName, final String lockHolder,
Copy link

Choose a reason for hiding this comment

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

unnecessary change

* @param jobs
* the jobs to be enqueued
* @throws IllegalArgumentException
* if the queue is null or empty or if the list of jobs is null
Copy link

Choose a reason for hiding this comment

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

looks to me that passing null as a list of jobs would result in a NPE

Copy link
Author

Choose a reason for hiding this comment

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

Correct. Fixed that.

jedis.quit();
}
}

private static void doWork(final List<Job> jobs, final Map<String, ? extends Class<? extends Runnable>> jobTypes,
Copy link

Choose a reason for hiding this comment

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

one small refactoring that we could do is changing the signature of this method & TestUtils.enqueueJobs to accept a single job and then use it wherever the list of jobs has 1 element.

worker creation could also be extracted to a method

Copy link
Author

Choose a reason for hiding this comment

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

I would not do this right now. Let's keep it as it is.

@@ -54,6 +54,9 @@ worker.end(true);
try { workerThread.join(); } catch (Exception e){ e.printStackTrace(); }
```

If enqueueing multiple jobs at the same time, there is `client.batchEnqueue(String queue, List<Job> jobs)` which does it
Copy link

Choose a reason for hiding this comment

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

should we maybe mention how does it do it and why is it more optimal?

Copy link
Author

Choose a reason for hiding this comment

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

I think this is too detailed for the README. The section is called 'Quickstart'.

@jack-kerouac jack-kerouac force-pushed the batch-enqueue-using-pipelining branch 3 times, most recently from fb932f3 to a3bd403 Compare December 19, 2018 09:16
maciejp and others added 2 commits December 19, 2018 10:19
Using Redis Pipelining is much faster than one-by-one enqueueing since there is a single Round-Trip-Time for the entire batch, instead of one RTT for each job. This improves the performance of enqueueing a large number of jobs considerably.

I decided against splitting large batches into multiple chunks (as recommended by https://redis.io/topics/pipelining#redis-pipelining), but mentioned it in the JavaDoc of this method. Thus, it is up to the user of this library to decide whether he wants to consider chunking the batch.
Not once per job in the list. Thus, I refactored the validation methods to be smaller. I decided against inlining `validateArguments()` method since I am not sure whether this is in line with the design principle of the author of this library.
@jack-kerouac
Copy link
Author

Will close this PR in favor of opening one to the upstream repo.

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.

2 participants