Browse Source

[beeswax] Raise QueryServerTimeoutException and rely on error_handler in beeswax API

Jenny Kim 10 years ago
parent
commit
3f87c1d

+ 16 - 20
apps/beeswax/src/beeswax/api.py

@@ -37,7 +37,7 @@ from beeswax.data_export import upload
 from beeswax.design import HQLdesign
 from beeswax.conf import USE_GET_LOG_API
 from beeswax.server import dbms
-from beeswax.server.dbms import expand_exception, get_query_server_config, QueryServerException
+from beeswax.server.dbms import expand_exception, get_query_server_config, QueryServerException, QueryServerTimeoutException
 from beeswax.views import authorized_get_design, authorized_get_query_history, make_parameterization_form,\
                           safe_get_design, save_design, massage_columns_for_json, _get_query_handle_and_state, \
                           _parse_out_hadoop_jobs
@@ -75,7 +75,6 @@ def error_handler(view_fn):
       if re.search('database is locked|Invalid query handle|not JSON serializable', message, re.IGNORECASE):
         response['status'] = 2 # Frontend will not display this type of error
         LOG.warn('error_handler silencing the exception: %s' % e)
-
       return JsonResponse(response)
   return decorator
 
@@ -114,11 +113,11 @@ def autocomplete(request, database=None, table=None, column=None, nested=None):
 
         inner_type = _get_complex_inner_type(current, extended_type, simple_type)
         response.update(inner_type)
-  except (QueryServerException, TTransportException), e:
+  except (QueryServerTimeoutException, TTransportException), e:
     response['code'] = 503
     response['error'] = e.message
   except Exception, e:
-    LOG.warn('Autocomplete data fetching error %s.%s: %s' % (database, table, e))
+    LOG.warn('Autocomplete data fetching error: %s' % e)
     response['code'] = 500
     response['error'] = e.message
 
@@ -644,6 +643,7 @@ def get_query_form(request):
   return query_form
 
 
+@error_handler
 def analyze_table(request, database, table, columns=None):
   app_name = get_app_name(request)
   query_server = get_query_server_config(app_name)
@@ -665,6 +665,7 @@ def analyze_table(request, database, table, columns=None):
   return JsonResponse(response)
 
 
+@error_handler
 def get_table_stats(request, database, table, column=None):
   app_name = get_app_name(request)
   query_server = get_query_server_config(app_name)
@@ -672,21 +673,19 @@ def get_table_stats(request, database, table, column=None):
 
   response = {'status': -1, 'message': '', 'redirect': ''}
 
-  try:
-    if column is not None:
-      stats = db.get_table_columns_stats(database, table, column)
-    else:
-      table = db.get_table(database, table)
-      stats = table.stats
+  if column is not None:
+    stats = db.get_table_columns_stats(database, table, column)
+  else:
+    table = db.get_table(database, table)
+    stats = table.stats
 
-    response['stats'] = stats
-    response['status'] = 0
-  except QueryServerException, e:
-    response['message'] = _('Failed to get table stats for table %s.%s: %s' % (database, table, e.message))
+  response['stats'] = stats
+  response['status'] = 0
 
   return JsonResponse(response)
 
 
+@error_handler
 def get_top_terms(request, database, table, column, prefix=None):
   app_name = get_app_name(request)
   query_server = get_query_server_config(app_name)
@@ -694,13 +693,10 @@ def get_top_terms(request, database, table, column, prefix=None):
 
   response = {'status': -1, 'message': '', 'redirect': ''}
 
-  try:
-    terms = db.get_top_terms(database, table, column, prefix=prefix, limit=int(request.GET.get('limit', 30)))
+  terms = db.get_top_terms(database, table, column, prefix=prefix, limit=int(request.GET.get('limit', 30)))
 
-    response['terms'] = terms
-    response['status'] = 0
-  except QueryServerException, e:
-    response['message'] = _('Failed to get table stats for table %s.%s: %s' % (database, table, e.message))
+  response['terms'] = terms
+  response['status'] = 0
 
   return JsonResponse(response)
 

+ 15 - 9
apps/beeswax/src/beeswax/server/dbms.py

@@ -107,6 +107,13 @@ class QueryServerException(Exception):
     self.message = message
 
 
+class QueryServerTimeoutException(Exception):
+
+  def __init__(self, message=''):
+    super(QueryServerTimeoutException, self).__init__(message)
+    self.message = message
+
+
 class NoSuchObjectException: pass
 
 
@@ -496,19 +503,18 @@ class HiveServer2Dbms(object):
       time.sleep(sleep_interval)
       curr = time.time()
 
+    # Query timed out, so attempt to cancel operation and raise exception
+    msg = "The query timed out after %(timeout)d seconds, canceled query." % {'timeout': timeout_sec}
+    LOG.warning(msg)
     try:
-      msg = "The query timed out after %(timeout)d seconds, canceled query [%(query)s]..." % \
-              {'timeout': timeout_sec, 'query': query.hql_query[:40]}
-      LOG.exception(msg)
       self.cancel_operation(handle)
-      raise QueryServerException(Exception(msg), message=msg)
-    except:
-      msg = "Failed to cancel query [%(query)s]..." % {'query': query.hql_query[:40]}
-      LOG.exception(msg)
+    except Exception, e:
+      msg = "Failed to cancel query."
+      LOG.warning(msg)
       self.close_operation(handle)
-      raise QueryServerException(Exception(msg), message=msg)
+      raise QueryServerException(e, message=msg)
 
-    return None
+    raise QueryServerTimeoutException(message=msg)
 
 
   def execute_next_statement(self, query_history, hql_query):

+ 1 - 1
apps/metastore/src/metastore/views.py

@@ -120,7 +120,7 @@ def show_tables(request, database=None):
 
     tables = db.get_tables(database=database)
   except Exception, e:
-    raise PopupException(_('Failed to retrieve tables for database % s' % database), detail=e)
+    raise PopupException(_('Failed to retrieve tables for database: %s' % database), detail=e)
 
   resp = render("tables.mako", request, {
     'breadcrumbs': [