Skip to content

Latest commit

 

History

History
94 lines (70 loc) · 9.49 KB

07_dispatcher_worker.md

File metadata and controls

94 lines (70 loc) · 9.49 KB

why? every software service needs instrumentation (logging, analytics, ...), one of the limitiations of some types of instrumentation is that they may cause a dramatic increase in service's execution time; this tutorial presents vangav backend's simple solution for this problem through isolating user-experience-related operations from instrumentation-related operations using worker services

dispatcher-worker design

what's a worker service and why use it

  • if you are unfamiliar with workers, think of it as a private secondary-backend service accessible only by the primary-backend service

  • generally, there are two types of operations, blocking and non-blocking; in this context blocking is any operation that doesn't finish rapidly (e.g.: network operations, disk operations, ...) and non-blocking is any operation that finishes rapidly (e.g.: in-memory calculations)

  • vangav backend has the following built-in Dispatchable Operations

    dispatchable explanation
    QueryDispatchable cassandra queries (insert, update and delete) select queries aren't dispatchable
    AndroidNotificationDispatchable android push notifications
    AppleNotificationDispatchable apple push notifications
    JavaEmailDispatchable java's built-in emails
    MailGunEmailDispatchable mailgun emails - mailgun is one of the recommended email services by google cloud
    TwilioSmsDispatchable twilio sms
    TwilioMmsDispatchable twilio mms
  • in most services (e.g.: facebook, instagram, snapchat, ...), there are two sets of blocking operations: real-time-needed and not-real-time-needed; let's say one posts a status update to Facebook:

    • a real-time-needed blocking operation would be to write the status update in the database before returning the request's response
    • not-real-time-needed blocking operations would be to write logs, update analytics, send push notifications to friends tagged in the status update, ...
  • separating the primary-backend from the worker (secondary-backend) enables allocating more resources (memory, instances, ...) to the primary-backend to ensure the fastest possible request-to-response time which leads to a great user experience

how to use dispatcher-worker(s)

  1. when generating a new service using vangav backend (e.g.: calculate sum), the last step says Generate worker [vos_calculate_sum_worker] for new project [vos_calculate_sum] ?: [Y/N]; enter Y to generate a worker service; generated workers has built-in support for cassandra queries and push notifications:
    • cassandra queries are added to the generated worker if the new service's config had one of more keyspace_name.keyspace config files
    • push notifications are added to the generated worker, if the new service's config has notifications set to true in the controllers.json config file
    • manually add twilio/email by adding their properties files (java_email_properties.prop, mail_gun_email_properties.prop, twilio_properties.prop) and their jars from lib to the generated worker service's conf/prop and lib directories respectively
  2. in the primary-backend-instance, set workers_topology to the ip(s)/port(s) of the worker(s)
  3. at any point during request-processing (before-or-after response) you can enqueue a DispatchMessage into the request's Dispatcher as shown in the usage examples below; add as many dispatch messages as needed to the request's dispatcher and all these messages get automatically dispatched to the worker(s) at the end of the request's processing
  4. make sure to start the worker service (using its _run.sh script) before starting the primary service
  5. you don't need to write a single line of code in the worker - it just works :)); just double check that every thing is correct in its properties files

usage examples

  request.getDispatcher().addDispatchMessage(
    CountPerWeek.i().getQueryDispatchableIncrementCommentsReceivedCount(
      postOwnerUserId.toString()
      + Constants.kCassandraIdConcat
      + CalendarFormatterInl.concatCalendarFields(
        request.getStartCalendar(),
        Calendar.YEAR,
        Calendar.WEEK_OF_YEAR) ) );
  request.getDispatcher().addDispatchMessage(
    new AppleNotificationDispatchable(
      new AppleNotificationBuilder(deviceToken)
        .alertBody(commenterName + " commented on your photo")
        .badgeNumber(1)
        .build() ) );
  request.getDispatcher().addDispatchMessage(
    new AndroidNotificationDispatchable(
      new AndroidNotification(
        new Message.Builder()
          .collapseKey(commenterName + " commented on your photo")
          .build(),
        deviceToken) ) );

exercise

when would you use a worker service?

next tutorial -> debugging

explains how to start and use the debugger

share

facebook share twitter share pinterest share google plus share linkedin share

free consulting

vangav's consultant