如何通过龙卷风将阻止代码正确转换为异步?

时间:2016-03-11 03:37:44

标签: performance asynchronous tornado

所以我很难理解如何将我的龙卷风代码转换为更加异步。我首先使用pymongo和mongothon。所以请不要建议我使用电机。电机不能与mongothon一起使用,我们将它用于模型和模式验证。好的,那就是说...所有的代码都是以阻塞可以发生的方式编写的。我们运行4线龙卷风。目前只有一小群人使用该应用程序,甚至我们设法锁定系统,现在我们正在进行扩展。为了处理规模,我需要开始思考异步(我认为)和转换代码。让我们看一下渲染到主页的代码。

import app.basic
import operator
import tornado.web

from datetime import datetime, timedelta
from dateutil import tz

from lib import chaindb, placement_historydb, revenue_datadb, sitesdb, serverlogsdb, tagsdb

##################
### ADMIN HOMEPAGE
##################
class Home(app.basic.BaseHandler):
  # list the available admin tools
  @tornado.web.authenticated
  def get(self):
    if self.get_secure_cookie("account_type")  not in ['admin']:
      self.redirect('/')
    else:
      view_format = self.get_argument('view_format', 'html')
      stats = {'ad_volume':0, 'int_ad_volume':0, 'mtd_revenue':0.0, 'avg_revenue':0.0}

      start_date = self.get_argument('start_date', '')

      if start_date == '':
        from_zone = tz.gettz('UTC')
        to_zone = tz.gettz('America/New_York')
        utc = datetime.utcnow()
        utc = utc.replace(tzinfo=from_zone)
        current_date = utc.astimezone(to_zone)
        start_date = current_date.strftime("%Y-%m-%d")

      date_parts = start_date.split('-')
      stats['site_totals'] = {}
      site_totals = serverlogsdb.get_site_total_for_day(date_parts[0], date_parts[1], date_parts[2], 'first')
      for site in site_totals:
        if site['total'] > 100:
          stats['site_totals'][site['_id']] = site['total']
      stats['site_totals'] = sorted(stats['site_totals'].items(), key=operator.itemgetter(1), reverse=True)
      stats['all_ad_volume'] = serverlogsdb.get_total_for_day(date_parts[0], date_parts[1], date_parts[2])
      stats['ad_volume'] = serverlogsdb.get_total_for_day(date_parts[0], date_parts[1], date_parts[2],'first')
      stats['all_int_ad_volume'] = serverlogsdb.get_int_total_for_day(date_parts[0], date_parts[1], date_parts[2])
      stats['int_ad_volume'] = serverlogsdb.get_int_total_for_day(date_parts[0], date_parts[1], date_parts[2],'first')
      try:
        stats['mtd_revenue'] = revenue_datadb.get_total_by_date(start_date)['revenue']
      except:
        pass
      try:
        stats['avg_revenue'] = float(stats['mtd_revenue'])/(float(start_date.split('-')[2])-1)
      except:
        stats['avg_revenue'] = 0.0

      notes = []

      yesterday = datetime.today() + timedelta(days=-1)
      two_days_ago = datetime.today() + timedelta(days=-2)

      yesterday_live_placements = placement_historydb.get_live_placement_count_for_date(yesterday.strftime('%Y-%m-%d'))
      two_days_ago_live_placements = placement_historydb.get_live_placement_count_for_date(two_days_ago.strftime('%Y-%m-%d'))
      notes.append('<strong><a href="/admin/reports/placement_history">%s</a></strong> placements were considered live yesterday (vs. <strong>%s</strong> two days ago).' % (yesterday_live_placements, two_days_ago_live_placements))

      sites_created = sitesdb.get_sites_created(yesterday)
      slugs = []
      for site in sites_created:
        slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
      notes.append('<strong>%s</strong> site records have been created in the past 24 hours (%s).' % (len(sites_created), ', '.join(slugs)))

      chain_slugs_updated = chaindb.get_chains_updated(yesterday)
      slugs = []
      for site in chain_slugs_updated:
        slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site, site))
      notes.append('<strong>%s</strong> chains have been updated in the past 24 hours (%s).' % (len(chain_slugs_updated), ', '.join(slugs)))

      tag_slugs_updated = tagsdb.get_tags_updated(yesterday)
      slugs = []
      for site in tag_slugs_updated:
        slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site, site))
      notes.append('<strong>%s</strong> tags have been updated in the past 24 hours (%s).' % (len(tag_slugs_updated), ', '.join(slugs)))

      sites_updated = sitesdb.get_sites_updated(yesterday)
      archived = 0
      slugs = []
      for site in sites_updated:
        # updated.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
        if site['site_status'] == 'archived':
          slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
          archived += 1
      if len(sites_updated) > 0:
        notes.append('<strong>%s</strong> site records have been updated in the past 24 hours.' % (len(sites_updated)))
        notes.append('<strong>%s</strong> sites appear to have been archived in the past 24 hours (%s).' % (archived, ', '.join(slugs)))

      latest_revenue_pull = revenue_datadb.get_latest_pull_date()
      notes.append('The latest <a href="/admin/reports/revenue_providers">REVENUE PROVIDER</a> data pull was on <strong>%s</strong>' % latest_revenue_pull)

      records = revenue_datadb.get_records_by_date(latest_revenue_pull)
      revenue = 0.0
      total_impressions = 0
      filled_impressions = 0
      tag_count = 0
      for record in records:
        tag_count += len(record['records'])
        for rec in record['records']:
          try:
            rec['REVENUE'] = float(str(rec['REVENUE']).replace('$','').replace(',',''))
          except:
            rec['REVENUE'] = 0.0
          revenue += rec['REVENUE']
          try:
            total_impressions += int(rec['TOTAL_IMPRESSIONS'])
          except:
            pass
          try:
            filled_impressions += int(rec['FILLED_IMPRESSIONS'])
          except:
            pass

      stats['revenue_provider_revenue'] = revenue
      stats['revenue_provider_tag_count'] = tag_count
      # notes.append('On <strong>%s</strong> revenue providers reported <strong>$%s</strong> revenue across <strong>%s</strong> tags' % (latest_revenue_pull, "{:20,.2f}".format(revenue), "{:20,}".format(tag_count)))
      try:
        notes.append('On <strong>%s</strong> revenue providers reported <strong>%s</strong> total impressions and <strong>%s</strong> fill (%s %%)' % (latest_revenue_pull, "{:20,}".format(total_impressions), "{:20,}".format(filled_impressions), "{:20,.2f}".format((float(filled_impressions)/float(total_impressions) * 100))))
      except:
        pass

      notes.append('The last <a href="/admin/reports/subsidies?start_date=%s&end_date=%s">subsidy report</a> is available for %s' % (latest_revenue_pull, latest_revenue_pull, latest_revenue_pull))

      if view_format == 'html':
        self.render('admin/homepage.html', notes=notes, start_date=start_date, stats=stats)
      else:
        data = {'notes':notes, 'start_date':start_date, 'stats':stats}
        self.api_response(dat

A)

正如您所看到的,代码的很大一部分是mongo,聚合等......然后模板使用存储在变量notes,start_date,stats中的项目...... 我试图做的是删除所有代码并将其放在一个单独的方法中。产生未来,将未来解包为get请求中的三个变量(notes,start_date,stats)并生成模板。这根本不起作用,请参阅下面的代码

import app.basic
import operator
import tornado.web
from tornado import gen


from datetime import datetime, timedelta
from dateutil import tz

from lib import chaindb, placement_historydb, revenue_datadb, sitesdb, serverlogsdb, tagsdb

##################
### ADMIN HOMEPAGE
##################
class Home(app.basic.BaseHandler):
  @gen.coroutine
  def stats_notes(self):
    stats = {'ad_volume':0, 'int_ad_volume':0, 'mtd_revenue':0.0, 'avg_revenue':0.0}

    from_zone = tz.gettz('UTC')
    to_zone = tz.gettz('America/New_York')
    utc = datetime.utcnow()
    utc = utc.replace(tzinfo=from_zone)
    current_date = utc.astimezone(to_zone)
    start_date = current_date.strftime("%Y-%m-%d")

    date_parts = start_date.split('-')
    stats['site_totals'] = {}
    site_totals = serverlogsdb.get_site_total_for_day(date_parts[0], date_parts[1], date_parts[2], 'first')
    for site in site_totals:
      if site['total'] > 100:
        stats['site_totals'][site['_id']] = site['total']
    stats['site_totals'] = sorted(stats['site_totals'].items(), key=operator.itemgetter(1), reverse=True)
    stats['all_ad_volume'] = serverlogsdb.get_total_for_day(date_parts[0], date_parts[1], date_parts[2])
    stats['ad_volume'] = serverlogsdb.get_total_for_day(date_parts[0], date_parts[1], date_parts[2],'first')
    stats['all_int_ad_volume'] = serverlogsdb.get_int_total_for_day(date_parts[0], date_parts[1], date_parts[2])
    stats['int_ad_volume'] = serverlogsdb.get_int_total_for_day(date_parts[0], date_parts[1], date_parts[2],'first')
    try:
      stats['mtd_revenue'] = revenue_datadb.get_total_by_date(start_date)['revenue']
    except:
      pass
    try:
      stats['avg_revenue'] = float(stats['mtd_revenue'])/(float(start_date.split('-')[2])-1)
    except:
      stats['avg_revenue'] = 0.0

    notes = []

    yesterday = datetime.today() + timedelta(days=-1)
    two_days_ago = datetime.today() + timedelta(days=-2)

    yesterday_live_placements = placement_historydb.get_live_placement_count_for_date(yesterday.strftime('%Y-%m-%d'))
    two_days_ago_live_placements = placement_historydb.get_live_placement_count_for_date(two_days_ago.strftime('%Y-%m-%d'))
    notes.append('<strong><a href="/admin/reports/placement_history">%s</a></strong> placements were considered live yesterday (vs. <strong>%s</strong> two days ago).' % (yesterday_live_placements, two_days_ago_live_placements))

    sites_created = sitesdb.get_sites_created(yesterday)
    slugs = []
    for site in sites_created:
      slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
    notes.append('<strong>%s</strong> site records have been created in the past 24 hours (%s).' % (len(sites_created), ', '.join(slugs)))

    chain_slugs_updated = chaindb.get_chains_updated(yesterday)
    slugs = []
    for site in chain_slugs_updated:
      slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site, site))
    notes.append('<strong>%s</strong> chains have been updated in the past 24 hours (%s).' % (len(chain_slugs_updated), ', '.join(slugs)))

    tag_slugs_updated = tagsdb.get_tags_updated(yesterday)
    slugs = []
    for site in tag_slugs_updated:
      slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site, site))
    notes.append('<strong>%s</strong> tags have been updated in the past 24 hours (%s).' % (len(tag_slugs_updated), ', '.join(slugs)))

    sites_updated = sitesdb.get_sites_updated(yesterday)
    archived = 0
    slugs = []
    for site in sites_updated:
      # updated.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
      if site['site_status'] == 'archived':
        slugs.append('<a href="/admin/sites/settings?slug=%s">%s</a>' % (site['slug'], site['slug']))
        archived += 1
    if len(sites_updated) > 0:
      notes.append('<strong>%s</strong> site records have been updated in the past 24 hours.' % (len(sites_updated)))
      notes.append('<strong>%s</strong> sites appear to have been archived in the past 24 hours (%s).' % (archived, ', '.join(slugs)))

    latest_revenue_pull = revenue_datadb.get_latest_pull_date()
    notes.append('The latest <a href="/admin/reports/revenue_providers">REVENUE PROVIDER</a> data pull was on <strong>%s</strong>' % latest_revenue_pull)

    records = revenue_datadb.get_records_by_date(latest_revenue_pull)
    revenue = 0.0
    total_impressions = 0
    filled_impressions = 0
    tag_count = 0
    for record in records:
      tag_count += len(record['records'])
      for rec in record['records']:
        try:
          rec['REVENUE'] = float(str(rec['REVENUE']).replace('$','').replace(',',''))
        except:
          rec['REVENUE'] = 0.0
        revenue += rec['REVENUE']
        try:
          total_impressions += int(rec['TOTAL_IMPRESSIONS'])
        except:
          pass
        try:
          filled_impressions += int(rec['FILLED_IMPRESSIONS'])
        except:
          pass

    stats['revenue_provider_revenue'] = revenue
    stats['revenue_provider_tag_count'] = tag_count
    # notes.append('On <strong>%s</strong> revenue providers reported <strong>$%s</strong> revenue across <strong>%s</strong> tags' % (latest_revenue_pull, "{:20,.2f}".format(revenue), "{:20,}".format(tag_count)))
    try:
      notes.append('On <strong>%s</strong> revenue providers reported <strong>%s</strong> total impressions and <strong>%s</strong> fill (%s %%)' % (latest_revenue_pull, "{:20,}".format(total_impressions), "{:20,}".format(filled_impressions), "{:20,.2f}".format((float(filled_impressions)/float(total_impressions) * 100))))
    except:
      pass

    notes.append('The last <a href="/admin/reports/subsidies?start_date=%s&end_date=%s">subsidy report</a> is available for %s' % (latest_revenue_pull, latest_revenue_pull, latest_revenue_pull))

    yield gen.Task([notes, start_date, stats])

  @tornado.web.authenticated
  @gen.coroutine
  def get(self):
    if self.get_secure_cookie("account_type")  not in ['admin']:
      self.redirect('/')
    else:
      view_format = self.get_argument('view_format', 'html')
      results = self.stats_notes()
      notes, start_date, stats = results

      if view_format == 'html':
        yield gen.Task(self.render('admin/homepage.html', notes=notes, start_date=start_date, stats=stats))
      else:
        data = {'notes':notes, 'start_date':start_date, 'stats':stats}
        yield gen.Task( self.api_response(data))

我用它来产生线程以及您期望的烧瓶应用程序的其他此类项目。我也不确定我是否以正确的方式解决这个问题。那么如何才能让异步工作?有一个更好的方法吗?是否需要同步才能很好地扩展?

0 个答案:

没有答案