Skip to content

Commit 4a53d90

Browse files
committed
simplified code
1 parent 95cba05 commit 4a53d90

File tree

1 file changed

+15
-80
lines changed

1 file changed

+15
-80
lines changed

app.py

Lines changed: 15 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -23,99 +23,37 @@
2323
sampler=ProbabilitySampler(rate=1.0),
2424
)
2525

26-
# Get Pool Size
27-
if 'POOL_SIZE' in os.environ:
28-
pool_size = int(os.environ['POOL_SIZE'])
29-
else:
30-
pool_size = 10
31-
3226
# Setup Flask Restful framework
3327
api = Api(app)
3428
parser = reqparse.RequestParser()
3529
parser.add_argument('customer')
3630

37-
# Implement manual connection pooling
31+
# Implement manual round-robin connection pooling
3832
class ConnectionManager(object):
3933
__instance = None
40-
__conn_index = 0
41-
__conn_dict = {}
34+
__connection = None
4235
__lock = Lock()
4336

4437
def __new__(cls):
4538
if ConnectionManager.__instance is None:
4639
ConnectionManager.__instance = object.__new__(cls)
47-
return ConnectionManager.__instance
48-
49-
def is_retriable(self, value):
50-
# https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/appendix-a-odbc-error-codes
51-
RETRY_CODES = [
52-
"08S01", # ODBC - Communication link failure
53-
"8001",
54-
"42000",
55-
"1204", # The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.
56-
"1205", # Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction
57-
"1222", # Lock request time out period exceeded.
58-
"49918", # Cannot process request. Not enough resources to process request.
59-
"49919", # Cannot process create or update request. Too many create or update operations in progress for subscription "%ld".
60-
"49920", # Cannot process request. Too many operations in progress for subscription "%ld".
61-
"4060", # Cannot open database "%.*ls" requested by the login. The login failed.
62-
"4221", # Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary.
63-
64-
"40143", # The service has encountered an error processing your request. Please try again.
65-
"40613", # Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'.
66-
"40501", # The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.
67-
"40540", # The service has encountered an error processing your request. Please try again.
68-
"40197", # The service has encountered an error processing your request. Please try again. Error code %d.
69-
"10929", # Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. Otherwise, please try again later.
70-
"10928", # Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637.
71-
"10060", # An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060)
72-
"10054", # The data value for one or more columns overflowed the type used by the provider.
73-
"10053", # Could not convert the data value due to reasons other than sign mismatch or overflow.
74-
"233", # A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233)
75-
"64",
76-
"20",
77-
"0"
78-
]
79-
result = value in RETRY_CODES
80-
return result
40+
return ConnectionManager.__instance
8141

8242
def __getConnection(self):
83-
self.__lock.acquire()
84-
idx = self.__conn_index + 1
85-
if idx > pool_size: idx = 1
86-
self.__conn_index = idx
87-
self.__lock.release()
88-
89-
if not idx in self.__conn_dict.keys():
90-
application_name = ";APP={0}-{1}".format(socket.gethostname(), idx)
91-
conn = pyodbc.connect(os.environ['SQLAZURECONNSTR_WWIF'] + application_name)
92-
self.__lock.acquire()
93-
self.__conn_dict.update( { idx: conn } )
94-
self.__lock.release()
95-
else:
96-
self.__lock.acquire()
97-
conn = self.__conn_dict[idx]
98-
self.__lock.release()
43+
if (self.__connection == None):
44+
application_name = ";APP={0}".format(socket.gethostname())
45+
self.__connection = pyodbc.connect(os.environ['SQLAZURECONNSTR_WWIF'] + application_name)
9946

100-
return (idx, conn)
101-
102-
def __removeConnection(self, idx):
103-
self.__lock.acquire()
104-
if idx in self.__conn_dict.keys():
105-
del(self.__conn_dict[idx])
106-
self.__lock.release()
47+
return self.__connection
10748

108-
def __removeConnections(self):
109-
self.__lock.acquire()
110-
self.__conn_dict.clear()
111-
self.__lock.release()
49+
def __removeConnection(self):
50+
self.__connection = None
11251

113-
@retry(stop=stop_after_attempt(3), wait=wait_fixed(10), after=after_log(app.logger, logging.DEBUG))
52+
@retry(stop=stop_after_attempt(3), wait=wait_fixed(10), retry=retry_if_exception_type(pyodbc.Error), after=after_log(app.logger, logging.DEBUG))
11453
def executeQueryJSON(self, procedure, payload=None):
11554
result = {}
11655
try:
117-
(idx, conn) = self.__getConnection()
118-
app.logger.info(f"Connection Index: {idx}")
56+
conn = self.__getConnection()
11957

12058
cursor = conn.cursor()
12159

@@ -135,14 +73,11 @@ def executeQueryJSON(self, procedure, payload=None):
13573
except pyodbc.Error as e:
13674
if isinstance(e, pyodbc.ProgrammingError) or isinstance(e, pyodbc.OperationalError):
13775
app.logger.error(f"Error: {e.args[0]}")
138-
if self.is_retriable(e.args[0]):
76+
if e.args[0] == "08S01":
13977
# If there is a "Communication Link Failure" error,
140-
# then all connections must be removed
141-
# as all will be in an invalid state
142-
if (e.args[0] == "08S01"):
143-
self.__removeConnections()
144-
else:
145-
self.__removeConnection(idx)
78+
# then connection must be removed
79+
# as it will be in an invalid state
80+
self.__removeConnection()
14681
raise
14782

14883
return result

0 commit comments

Comments
 (0)