Browse Source

[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 years ago
parent
commit
21646ba

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

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

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