Jelajahi Sumber

[notebook] Cache the JDBC connection by snippet type and user

AFAI can tell, the real connection open when we do db.connect() and this is something
we close.

At the same fix when no username are provided in the options of the JDBC snippet.
Romain Rigaux 10 tahun lalu
induk
melakukan
21646ba85f

+ 5 - 5
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -93,8 +93,8 @@ def get_api(user, snippet, fs, jt):
   interpreter = [interpreter for interpreter in get_interpreters() if interpreter['type'] == snippet['type']]
   if not interpreter:
     raise PopupException(_('Snippet type %(type)s is not configured in hue.ini') % snippet)
-  interface = interpreter[0]['interface']
-  options = interpreter[0]['options']
+  interpreter = interpreter[0]
+  interface = interpreter['interface']
 
   if interface == 'hiveserver2':
     return HS2Api(user)
@@ -107,7 +107,7 @@ def get_api(user, snippet, fs, jt):
   elif interface == 'mysql':
     return MySqlApi(user)
   elif interface == 'jdbc':
-    return JdbcApi(user, options=options)
+    return JdbcApi(user, interpreter=interpreter)
   elif interface == 'pig':
     return PigApi(user, fs=fs, jt=jt)
   else:
@@ -122,11 +122,11 @@ def _get_snippet_session(notebook, snippet):
 
 class Api(object):
 
-  def __init__(self, user, fs=None, jt=None, options=None):
+  def __init__(self, user, fs=None, jt=None, interpreter=None):
     self.user = user
     self.fs = fs
     self.jt = jt
-    self.options = options
+    self.interpreter = interpreter
 
   def create_session(self, lang, properties=None):
     return {

+ 13 - 6
desktop/libs/notebook/src/notebook/connectors/jdbc.py

@@ -50,18 +50,21 @@ def query_error_handler(func):
 
 class JdbcApi(Api):
 
-  def __init__(self, user, fs=None, jt=None, options=None):
+  def __init__(self, user, fs=None, jt=None, interpreter=None):
     global API_CACHE
-    Api.__init__(self, user, fs=fs, jt=jt, options=options)
+    Api.__init__(self, user, fs=fs, jt=jt, interpreter=interpreter)
 
     self.db = None
+    self.options = interpreter['options']
 
-    if self.options['user'] in API_CACHE:
-      self.db = API_CACHE[self.options['user']]
+    if self.cache_key in API_CACHE:
+      self.db = API_CACHE[self.cache_key]
     elif 'password' in self.options:
-      self.db = API_CACHE[self.options['user']] = Jdbc(self.options['driver'], self.options['url'], self.options['user'], self.options['password'])
+      username = self.options.get('user') or user.username
+      self.db = API_CACHE[self.cache_key] = Jdbc(self.options['driver'], self.options['url'], username, self.options['password'])
 
   def create_session(self, lang=None, properties=None):
+    global API_CACHE
     props = super(JdbcApi, self).create_session(lang, properties)
 
     properties = dict([(p['name'], p['value']) for p in properties]) if properties is not None else {}
@@ -71,7 +74,7 @@ class JdbcApi(Api):
       if 'password' in properties:
         user = properties.get('user') or self.options.get('user')
         props['properties'] = {'user': user}
-        self.db = API_CACHE[user] = Jdbc(self.options['driver'], self.options['url'], user, properties.pop('password'))
+        self.db = API_CACHE[self.cache_key] = Jdbc(self.options['driver'], self.options['url'], user, properties.pop('password'))
 
     if self.db is None:
       raise AuthenticationRequired()
@@ -152,6 +155,10 @@ class JdbcApi(Api):
 
     return response
 
+  @property
+  def cache_key(self):
+    return '%s-%s' % (self.interpreter['name'], self.user.username)
+
 
 class Assist():