Skip to content

Commit d70f151

Browse files
d-w-moorealanking
authored andcommitted
[#562] release old connection when redirecting
When data objects were opened on redirected host connections, the old connection was being leaked (overwritten without being properly released.) The accumulation of irods.Connection object in source iRODSSession's active pool caused agents to pile up rather than closing down and exiting as they should. Eventually this caused a failure to connect from the client.
1 parent e061922 commit d70f151

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

irods/manager/data_object_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ def make_FileOpenRequest(**extra_opts):
428428
# This is the actual redirect.
429429
directed_sess = self.sess.clone(host = redirected_host)
430430
returned_values['session'] = directed_sess
431+
conn.release()
431432
conn = directed_sess.pool.get_connection()
432433
logger.debug('redirect_to_host = %s', redirected_host)
433434

irods/test/data_obj_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,35 @@ def test_touch_operation_does_not_work_when_given_a_collection__525(self):
20942094
with self.assertRaises(ex.InvalidInputArgument):
20952095
user_session.data_objects.touch(home_collection_path)
20962096

2097+
def test_client_redirect_lets_go_of_connections__issue_562(self):
2098+
self._skip_unless_connected_to_local_computer_by_other_than_localhost_synonym()
2099+
# Force data object connections to redirect by enforcing a non-equivalent hostname for their resource
2100+
total_conns = lambda session: len(session.pool.idle | session.pool.active)
2101+
with self.create_simple_resc(hostname = 'localhost') as resc_name:
2102+
# A reasonable number of data objects to create without eliciting problems.
2103+
# (But before resolution of #562, a NetworkException was eventually thrown from
2104+
# this test loop if a session cleanup() did not intervene between open() calls.)
2105+
REPS_TO_REPRODUCE_CONNECT_ERROR = 100
2106+
paths=[]
2107+
prev_conns = None
2108+
try:
2109+
# Try to exhaust connections
2110+
for n in range(REPS_TO_REPRODUCE_CONNECT_ERROR):
2111+
data_path = '{self.coll_path}/issue_562_test_obj_{n:03d}.dat'.format(**locals())
2112+
paths.append(data_path)
2113+
with self.sess.data_objects.open(data_path, 'w', **{kw.DEST_RESC_NAME_KW: resc_name}) as f:
2114+
pass
2115+
# Assert number of connections does not increase
2116+
current_conns = total_conns(self.sess)
2117+
if isinstance(prev_conns,int):
2118+
self.assertLessEqual(current_conns, prev_conns)
2119+
prev_conns = current_conns
2120+
finally:
2121+
# Clean up data objects before resource is deleted.
2122+
for data_path in paths:
2123+
if self.sess.data_objects.exists(data_path):
2124+
self.sess.data_objects.unlink(data_path, force = True)
2125+
20972126

20982127
if __name__ == '__main__':
20992128
# let the tests find the parent irods lib

0 commit comments

Comments
 (0)