Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f1675d4

Browse files
committed
added connection resiliency
1 parent 983f166 commit f1675d4

File tree

1 file changed

+72
-23
lines changed

1 file changed

+72
-23
lines changed

app.py

+72-23
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
1111
from opencensus.trace.samplers import ProbabilitySampler
1212

13+
pyodbc.pooling=False
14+
1315
# Initialize Flask
1416
app = Flask(__name__)
1517

@@ -25,32 +27,79 @@
2527
parser = reqparse.RequestParser()
2628
parser.add_argument('customer')
2729

30+
# Implement manual connection pooling
31+
class ConnectionManager(object):
32+
__instance = None
33+
__conn_index = 0
34+
__conn_dict = {}
35+
__lock = Lock()
36+
37+
def __new__(cls):
38+
if ConnectionManager.__instance is None:
39+
ConnectionManager.__instance = object.__new__(cls)
40+
return ConnectionManager.__instance
41+
42+
def __getConnection(self, conn_index):
43+
application_name = ";APP={0}-{1}".format(socket.gethostname(), conn_index)
44+
conn = pyodbc.connect(os.environ['SQLAZURECONNSTR_WWIF'] + application_name)
45+
return conn
46+
47+
48+
def getCursor(self):
49+
self.__lock.acquire()
50+
self.__conn_index += 1
51+
52+
if self.__conn_index > 9:
53+
self.__conn_index = 0
54+
55+
if not self.__conn_index in self.__conn_dict.keys():
56+
new_conn = self.__getConnection(self.__conn_index)
57+
self.__conn_dict.update( { self.__conn_index: new_conn } )
58+
59+
conn = self.__conn_dict[self.__conn_index]
60+
61+
try:
62+
cursor = conn.cursor()
63+
except e:
64+
if e.__class__ == pyodbc.ProgrammingError:
65+
conn == self.__getConnection(self.__conn_index)
66+
self.__conn_dict[self.__conn_index] = conn
67+
cursor = conn.cursor()
68+
69+
self.__lock.release()
70+
71+
return (self.__conn_index, cursor)
72+
73+
def removeConnection(self, idx):
74+
self.__lock.acquire()
75+
if idx in self.__conn_dict.keys():
76+
del(self.__conn_dict[idx])
77+
self.__lock.release()
78+
2879
class Queryable(Resource):
2980
def executeQueryJson(self, verb, payload=None):
3081
result = {}
31-
with pyodbc.connect(os.environ['SQLAZURECONNSTR_WWIF']) as conn:
32-
cursor = conn.cursor()
33-
entity = type(self).__name__.lower()
34-
procedure = f"web.{verb}_{entity}"
35-
try:
36-
if payload:
37-
cursor.execute(f"EXEC {procedure} ?", json.dumps(payload))
38-
else:
39-
cursor.execute(f"EXEC {procedure}")
40-
41-
result = cursor.fetchone()
42-
43-
if result:
44-
result = json.loads(result[0])
45-
else:
46-
result = {}
47-
48-
cursor.commit()
49-
except:
50-
conn.close()
51-
raise
52-
finally:
53-
cursor.close()
82+
(idx, cursor) = ConnectionManager().getCursor()
83+
entity = type(self).__name__.lower()
84+
procedure = f"web.{verb}_{entity}"
85+
try:
86+
if payload:
87+
cursor.execute(f"EXEC {procedure} ?", json.dumps(payload))
88+
else:
89+
cursor.execute(f"EXEC {procedure}")
90+
91+
result = cursor.fetchone()
92+
93+
if result:
94+
result = json.loads(result[0])
95+
else:
96+
result = {}
97+
98+
cursor.commit()
99+
except:
100+
ConnectionManager().removeConnection(idx)
101+
finally:
102+
cursor.close()
54103

55104
return result
56105

0 commit comments

Comments
 (0)