Просмотр исходного кода

HUE-8758 [editor] Add a skeleton of sync notebook api to submit a query

Romain 5 лет назад
Родитель
Сommit
9c26a0f421

+ 38 - 0
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -288,6 +288,44 @@ class Notebook(object):
     return _execute_notebook(request, notebook_data, snippet)
 
 
+  def execute_and_wait(self, request, timeout_sec=30.0, sleep_interval=0.5):
+      """
+      Run query and check status until it finishes or timeouts.
+
+      Check status until it finishes or timeouts.
+      """
+      task = self.execute(request, batch=False)
+      task['uuid'] = task['history_uuid']
+      status = self.check_status(task)
+      curr = time.time()
+      end = curr + timeout_sec
+
+      while curr <= end:
+        if status['status'] not in ('waiting', 'running'):
+          return task
+
+        status = self.check_status(task)
+        time.sleep(sleep_interval)
+        curr = time.time()
+
+      # Query timed out
+      # msg = "The query timed out after %(timeout)d seconds, canceled query." % {'timeout': timeout_sec}
+      # LOG.warning(msg)
+      # try:
+      #   self.cancel_operation(handle)
+      #   # get_api(request, snippet).cancel(notebook, snippet)
+      # except Exception as e:
+      #   msg = "Failed to cancel query."
+      #   LOG.warning(msg)
+      #   self.close_operation(handle)
+      #   raise QueryServerException(e, message=msg)
+
+      raise OperationTimeout()
+
+  def check_status(self, task):
+    pass
+
+
 def get_interpreter(connector_type, user=None):
   interpreter = [
     interpreter for interpreter in get_ordered_interpreters(user) if connector_type == interpreter['type']

+ 70 - 0
desktop/libs/notebook/src/notebook/connectors/base_tests.py

@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+## -*- coding: utf-8 -*-
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from builtins import object
+import json
+import sys
+
+from nose.tools import assert_equal, assert_true, assert_false
+
+from django.urls import reverse
+
+from desktop.lib.django_test_util import make_logged_in_client
+from useradmin.models import User
+
+from notebook.connectors.base import Notebook
+
+if sys.version_info[0] > 2:
+  from unittest.mock import patch, Mock
+else:
+  from mock import patch, Mock
+
+
+class TestNotebook(object):
+
+  def setUp(self):
+    self.client = make_logged_in_client(username="test", groupname="empty", recreate=True, is_superuser=False)
+    self.user = User.objects.get(username="test")
+
+
+  def test_execute_and_wait(self):
+    query = Notebook()
+    query.execute = Mock(return_value={'history_uuid': 1})
+
+
+    query.check_status = Mock(
+      side_effect=check_status_side_effect
+    )
+    request=Mock()
+
+
+    resp = query.execute_and_wait(request=request)
+    assert_equal(1, resp['uuid'])
+    assert_equal(2, query.check_status.call_count)
+
+
+iteration = 0
+def check_status_side_effect(value):
+  """First time query is still running, second time the execution is finished."""
+  global iteration
+
+  if iteration == 0:
+    iteration += 1
+    return {'status': 'running'}
+  else:
+    return {'status': 'done'}