on YouTube
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
using dispatcher - worker(s)
-
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
- 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]
; enterY
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
andlib
directories respectively
- in the primary-backend-instance, set
workers_topology
to the ip(s)/port(s) of the worker(s) - 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
- make sure to start the worker service (using its
_run.sh
script) before starting the primary service - 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
-
examples from instagram: HandlerComment
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) ) );
when would you use a worker service?
next tutorial -> debugging
explains how to start and use the debugger