Skip to content

Commit bd6c072

Browse files
committed
Improve thread safety of SwaggerClient
SwaggerClient discovers methods by reading a swagger document, creating instances of _ClientMethodFactory for paths in the swagger, and assigning those instances as class attributes of SwaggerClient. This means that a single instance of each _ClientMethodFactory is shared across threads. This is not so good because _ClientMethodFactories store state associated with requests. In particular, consider the following scenario: Thread-1: client = hca.dss.DSSClient() Thread-2: client = hca.dss.DSSClient() Thread-1: with client.get_file.stream(...) as handle: Thread-2: with client.get_file.stream(...) as handle: Thread-1: handle.raw.read() Depending on the execution of __enter__, Thread-1 may have just read from the file for Thread-2! Going on, Thread-1: __exit__ the with block Thread-2: handle.raw.read() Thread-2: __exit__ the with block Exception: NoneType has no attribute close() Or you know, something like that. This change makes the methods instance attributes.
1 parent b192f1a commit bd6c072

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

hca/util/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def _build_client_method(self, http_method, http_path, method_data):
468468
docstring += "\n\n" + _md2rst(method_data["description"])
469469
client_method.__doc__ = docstring
470470

471-
setattr(self.__class__, method_name, types.MethodType(client_method, SwaggerClient))
471+
setattr(self, method_name, types.MethodType(client_method, SwaggerClient))
472472
self.methods[method_name] = dict(method_data, entry_point=getattr(self, method_name)._cli_call,
473473
signature=client_method.__signature__, args=method_args)
474474

0 commit comments

Comments
 (0)