Giter Club home page Giter Club logo

dropwizard-worker's Introduction

dropwizard-worker

by Ian White, Stardog Ventures (@eonwhite)

This is a simple way to run asynchronous, decentralized jobs from a Dropwizard service.

This is particularly useful for crons scheduled with Amazon CloudWatch, as described in this great post by Dan McKinley (@mcfunley):

https://blog.skyliner.io/a-simple-pattern-for-jobs-and-crons-on-aws-2f965e43932f

But this worker also should be suitable for busy event-processing queues as well.

The basic pattern is:

  • Create any number of jobs you want to run. They need to implement Consumer<Map<String,Object>>, where the Map represents parameters to your method.
class MyCron implements Consumer<<Map<String,Object>> {
    public void consume(Map<String,Object> params) {
        // do something interesting here
    }
}
  • Build a WorkerMethods object that contains your list of WorkMethods available. Each WorkMethod gets a unique name for the method and a consumer. The names are important, since you'll use those names to call the method remotely.

If you have some really simple methods, you may want to consider inlining them as lambdas.

WorkerMethods methods = WorkerMethods.of(ImmutableList.of(
        WorkMethod.of("cron", new MyCron()),
        WorkMethod.of("ping", params -> System.out.println("pong"))
));
  • Configure a WorkerManager with your configuration, and the worker you are using for processing messages (normally SqsWorker)
env.lifecycle().manage(new WorkerManager(
        "worker",
        WorkerConfig.builder().maxThreads(20).build(),
        new SqsWorker(sqsClient, "queue-name", env.metrics()),
        env.metrics());
  • Send to the queue (from anywhere in your distributed system, such as for example CloudWatch) messages in the format:
  {"method":<method>}
  or
  {"method":<method>,"params":<params>}
  or
  {"method":<method>,"params":<params>,"at":<millis>}

Where method is the name of the method, params is an object containing your parameters, and at is a millisecond timestamp of the time the message was queued.

  • You can also send messages with a SqsSender like so:
SqsSender sender = new SqsSender(sqsClient, "queue-name")

Features:

  • Scales up for busy queues, launching threads and polling as quickly as possible, but automatically scaling down for infrequently used queues to save money and resources.
  • Builtin metrics for monitoring the state of your queue.
  • Includes a Dropwizard Task to run methods manually.

Timezone-aware crons

While it's generally better to schedule crons in UTC time, there are situations where you want a cron to run at a time in a local timezone (e.g. "9 am Eastern time"), adjusting for Daylight Savings time.

CloudWatch however does not support timezone-aware cron scheduling.

So the solution is:

  • Wrap your cron in a TimeZoneCron like so:
     TimeZoneCron.of(new MyCron(), ZoneId.of("America/New_York"))
  • TimeZoneCron will check for a dst property in the params. If dst is set to true, the cron will only run when in Daylight Savings Time, and if dst is false, the cron will only run when not in Daylight Savings Time.
  • Schedule two otherwise identical CloudWatch SQS events at the two potential times (e.g. 9am Eastern time could be either 13:00 UTC or 14:00 UTC), one with "dst":true and one with "dst":false
  • TimeZoneCron will run your cron only once, depending on whether it is currently DST or not.
  • The above could get screwy if you schedule your cron in the wee hours of the morning during the DST changeover period, so don't do that.

Redis PubSub

dropwizard-worker can send and receive messages in the same format using Redis PubSub via Jedis.

This can be useful instead of SQS in situations where you require multiple-subscriber behavior -- for example to have your appservers subscribe to a cache invalidation mechanism.

Because the Jedis client handles its own polling, there is no need to use the WorkerManager with Redis. You can instantiate RedisWorker to consume pubsub, and RedisSender to send messages.

See the RedisExample example for how this works.

dropwizard-worker's People

Contributors

eonwhite avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

markfreedman nkba

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.