Here is a case, when one must bring in parallelism into the backend server.
I am willing to query N ELB's, each for 5 different queries, and send the result back to the web client.
The backend is Tornado, and according to what I have read many times in the docs, in the past, I should be able to get several tasks processed in parallel if I use @gen.Task or gen.coroutine.
However, I must be missing something in here, as all my requests are (20 in number, 4 elbs * 5 queries) are processed one after another.
def query_elb(fn, region, elb_name, period, callback):
callback(fn (region, elb_name, period))
class DashboardELBHandler(RequestHandler):
@tornado.gen.coroutine
def get_elb_info(self, region, elb_name, period):
elbReq = yield gen.Task(query_elb, ELBSumRequest, region, elb_name, period)
elb2XX = yield gen.Task(query_elb, ELBBackend2XX, region, elb_name, period)
elb3XX = yield gen.Task(query_elb, ELBBackend3XX, region, elb_name, period)
elb4XX = yield gen.Task(query_elb, ELBBackend4XX, region, elb_name, period)
elb5XX = yield gen.Task(query_elb, ELBBackend5XX, region, elb_name, period)
raise tornado.gen.Return(
[
elbReq,
elb2XX,
elb3XX,
elb4XX,
elb5XX,
]
)
@tornado.web.authenticated
@tornado.web.asynchronous
@tornado.gen.coroutine
def post(self):
ret = []
period = self.get_argument("period", "5m")
cloud_deployment = db.foo.bar.baz()
for region, deployment in cloud_deployment.iteritems():
elb_name = deployment["elb"][0]
res = yield self.get_elb_info(region, elb_name, period)
ret.append(res)
self.push_json(ret)
def ELBQuery(region, elb_name, range_name, metric, statistic, unit):
dimensions = { u"LoadBalancerName": [elb_name] }
(start_stop , period) = calc_range(range_name)
cw = boto.ec2.cloudwatch.connect_to_region(region)
data_points = cw.get_metric_statistics( period, start, stop,
metric, "AWS/ELB", statistic, dimensions, unit)
return data_points
ELBSumRequest = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "RequestCount", "Sum", "Count")
ELBLatency = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "Latency", "Average", "Seconds")
ELBBackend2XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_2XX", "Sum", "Count")
ELBBackend3XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_3XX", "Sum", "Count")
ELBBackend4XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_4XX", "Sum", "Count")
ELBBackend5XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_5XX", "Sum", "Count")