)]}'
{"zuul/zk/__init__.py":[{"author":{"_account_id":27582,"name":"Simon Westphahl","email":"simon.westphahl@bmw.de","username":"simon.westphahl"},"change_message_id":"99bd32b5af1747f2fcadb2cf40c371bdd9674c79","unresolved":false,"context_lines":[{"line_number":60,"context_line":"zookeper_class \u003d ZooKeeper"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"def connect_zookeeper(*args, **kwargs) -\u003e ZooKeeper:"},{"line_number":64,"context_line":"    hosts: Optional[str] \u003d None"},{"line_number":65,"context_line":"    tls_key: Optional[str] \u003d kwargs.get(\u0027tls_key\u0027)"},{"line_number":66,"context_line":"    tls_cert: Optional[str] \u003d kwargs.get(\u0027tls_cert\u0027)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f560f44_901c2a78","line":63,"updated":"2020-10-07 10:43:15.000000000","message":"It feels like this function is now doing a little too much and it\u0027s also hard to see the different ways you can call it. How about adding a `from_config()` class methods to  ZooKeeperConnection that allow creating a connection from a configparser? E.g. something like\n\nclass ZooKeeperConnection(object):\n    def __init__(\n        self,\n        hosts: Union[str, List[str]],\n        timeout: int \u003d 120,\n        tls_key: Optional[str] \u003d None,\n        tls_cert: Optional[str] \u003d None,\n        tls_ca: Optional[str] \u003d None,\n        read_only: bool \u003d False,\n        enable_cache: bool \u003d True,\n    ):\n        self.log \u003d logging.getLogger(\"zuul.zk.ZooKeeperConnection\")\n        self.zookeeper: Optional[ZooKeeper] \u003d None\n        self.hosts \u003d hosts\n        self.timeout \u003d timeout\n        self.tls_key \u003d tls_key\n        self.tls_cert \u003d tls_cert\n        self.tls_ca \u003d tls_ca\n        self.read_only \u003d read_only\n\n    def __enter__(self) -\u003e ZooKeeper:\n        self.log.debug(\"Establishing connection...\")\n        self.zookeeper \u003d self.connect()\n        return self.zookeeper\n\n    def __exit__(self, kind: Any, value: Any, traceback: Optional[Any]):\n        self.log.debug(\"Destroying connection...\")\n        if self.zookeeper:\n            self.zookeeper.disconnect()\n\n    def connect(self) -\u003e ZooKeeper:\n        zookeeper \u003d zookeeper_class(enable_cache\u003dself.enable_cache)\n        zookeeper.client.connect(\n            hosts\u003dself.hosts,\n            timeout\u003dself.timeout,\n            tls_key\u003dself.tls_key,\n            tls_cert\u003dself.tls_cert,\n            tls_ca\u003dself.tls_ca,\n            read_only\u003dself.read_only,\n        )\n        return zookeeper\n\n    @classmethod\n    def from_config(cls, config: configparser.ConfigParser) -\u003e ZooKeeperConnection:\n        hosts \u003d get_default(config, \"zookeeper\", \"hosts\", None)\n        if not hosts:\n            raise Exception(\"The zookeeper hosts config value is required\")\n        tls_key \u003d get_default(config, \"zookeeper\", \"tls_key\")\n        tls_cert \u003d get_default(config, \"zookeeper\", \"tls_cert\")\n        tls_ca \u003d get_default(config, \"zookeeper\", \"tls_ca\")\n        timeout \u003d float(get_default(config, \"zookeeper\", \"session_timeout\", 120))\n\n        return cls(hosts\u003dhosts, tls_key\u003dtls_key, tls_cert\u003dtls_cert, timeout\u003dtimeout)\n\nThis way you don\u0027t need to use a separate `connect_zookeeper()` method and clients can directly use the ZooKeeperConnection wrapper:\n\n    with ZooKeeperConnection.from_config(config) as zk:\n        # ...\n\nOr if you want to use the Zookeeper instance directly:\n\n    connection \u003d ZooKeeperConnection.from_config(config)\n    self.zk \u003d connection.connect()","commit_id":"92626ed0e7ccbc149b96e4fa2ef7deb4b9a95528"},{"author":{"_account_id":30637,"name":"Jan Kubovy","email":"jan.kubovy@bmw.de","username":"kubovy"},"change_message_id":"a4e929400816d07f1b05b25db28ebfde40049c48","unresolved":false,"context_lines":[{"line_number":60,"context_line":"zookeper_class \u003d ZooKeeper"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"def connect_zookeeper(*args, **kwargs) -\u003e ZooKeeper:"},{"line_number":64,"context_line":"    hosts: Optional[str] \u003d None"},{"line_number":65,"context_line":"    tls_key: Optional[str] \u003d kwargs.get(\u0027tls_key\u0027)"},{"line_number":66,"context_line":"    tls_cert: Optional[str] \u003d kwargs.get(\u0027tls_cert\u0027)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f560f44_41c92658","line":63,"in_reply_to":"9f560f44_901c2a78","updated":"2020-10-07 13:45:16.000000000","message":"Done","commit_id":"92626ed0e7ccbc149b96e4fa2ef7deb4b9a95528"},{"author":{"_account_id":27582,"name":"Simon Westphahl","email":"simon.westphahl@bmw.de","username":"simon.westphahl"},"change_message_id":"d80a3d3e133c7a7a46cad3e667c06df06d8255d6","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_3d2ad3e6","line":156,"updated":"2020-10-21 08:07:24.000000000","message":"Looking at this now, I\u0027m wondering why we need a different ZooKeeperConnection class besides the ZooKeeperClient?","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":27582,"name":"Simon Westphahl","email":"simon.westphahl@bmw.de","username":"simon.westphahl"},"change_message_id":"793b121ccb191537b0a065c37a85defa35383f21","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_e799b31f","line":156,"in_reply_to":"3f65232a_342d9743","updated":"2020-10-26 06:34:44.000000000","message":"I think we are both wondering if this could be part of the ZooKeeperClient itself.","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":27952,"name":"Felix Edel","email":"felix.edel@bmw.de","username":"felix.schmidt"},"change_message_id":"30219dc9d8fcfc3faff4264200d206f4aeb43022","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_b13727e4","line":156,"in_reply_to":"3f65232a_3d2ad3e6","updated":"2020-10-21 14:11:10.000000000","message":"Same here. I\u0027m a little confused now about ZooKeeperClient vs ZooKeeperConnection.","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":27582,"name":"Simon Westphahl","email":"simon.westphahl@bmw.de","username":"simon.westphahl"},"change_message_id":"0650d2141912939b2690a2dc05c8f7b5e171b7b3","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_c01bbd18","line":156,"in_reply_to":"3f65232a_65211bb5","updated":"2020-10-26 11:14:54.000000000","message":"I think at this point there was no ZooKeeperClient or at least I did not fully see how they interact. Now with a ZooKeeperClient and a ZooKeeperConnection I was just wondering if they could be combined so that we only have one class responsible for working with a Zookeeper connection. Also just making suggestions here to start a discussion :)","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":30637,"name":"Jan Kubovy","email":"jan.kubovy@bmw.de","username":"kubovy"},"change_message_id":"fe96ccca654f9b0cf4226703d98a48def980d680","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_342d9743","line":156,"in_reply_to":"3f65232a_b13727e4","updated":"2020-10-25 19:55:48.000000000","message":"ZooKeeperConnection was done to unify/simplify creating a ZooKeeperClient. It provides a way to configure connection using a ConfigParser and using parameters in constructor and can be used with a \"with\" block. It is a replacement of the previously used \"connect_zookeeper\" sugar function.","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":30637,"name":"Jan Kubovy","email":"jan.kubovy@bmw.de","username":"kubovy"},"change_message_id":"a391f5e4f189020107e9f23fa4419b2cb7968ff5","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"1f621f24_86b1e192","line":156,"in_reply_to":"3f65232a_c01bbd18","updated":"2020-11-02 10:37:49.000000000","message":"We can do that. The ZooKeeperConnection now deals with parsing configuration while ZooKeeperClient expects already prepared parameters. If there is no benefit of such separation merging those two should not be a problem.","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":30637,"name":"Jan Kubovy","email":"jan.kubovy@bmw.de","username":"kubovy"},"change_message_id":"e6a40ff15d24ec0944cdf329130c6b296a2bd949","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"class ZooKeeperConnection(object):"},{"line_number":157,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"3f65232a_65211bb5","line":156,"in_reply_to":"3f65232a_e799b31f","updated":"2020-10-26 10:39:57.000000000","message":"It could of course. I got inspired by your comment at patch 10 ;)","commit_id":"33906151d87f6f6ba03d2618f8edeb319e61bcfa"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"58b7ecf40e9df8e0f4c64096ba1e8c9a7397061f","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        pass"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class ZooKeeperConnection(object):"},{"line_number":159,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":26,"id":"9866d458_d774673e","line":158,"updated":"2021-02-12 15:34:31.000000000","message":"Nothing uses this class, and I\u0027m not sure what the intent is; all of our zk connections are going to be very long lived; essentially, we\u0027re never going to close them; why would we do this as a context manager?","commit_id":"97d6d3e2f421069cd8e8496640bd6eff7df9fa2e"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"879b7a8552f09cb695726da778da2c07a0443cb5","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        pass"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class ZooKeeperConnection(object):"},{"line_number":159,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":26,"id":"636affeb_25920ef8","line":158,"updated":"2021-02-12 15:40:47.000000000","message":"Sorry, that should say nothing uses this class as a connection manager.","commit_id":"97d6d3e2f421069cd8e8496640bd6eff7df9fa2e"},{"author":{"_account_id":27952,"name":"Felix Edel","email":"felix.edel@bmw.de","username":"felix.schmidt"},"change_message_id":"245836ea788c3bcb5afbc9515880211194ffcf70","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        pass"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class ZooKeeperConnection(object):"},{"line_number":159,"context_line":"    _zk_client_class \u003d ZooKeeperClient"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":26,"id":"3c641442_54c81b6b","line":158,"in_reply_to":"9866d458_d774673e","updated":"2021-02-12 15:40:06.000000000","message":"That\u0027s mainly what my cleanup in https://review.opendev.org/c/zuul/zuul/+/771442/10 is about. This connection class would be used in the \"Connect xyz to ZooKeeper\" changes (sometimes as a context manager), but I thought it would be nicer to have only a single class as entry point to ZooKeeper.\n\nAs the cleanup mentioned above was previously further up in the stack, I rebased it on top of this change to directly incorporate it as a fixup/squash commit. AFAIK I still have to adapt the \"Connect xyz to ZooKeeper\" patches to make that fully work as there might be some leftovers from the rebase.","commit_id":"97d6d3e2f421069cd8e8496640bd6eff7df9fa2e"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"885443db22fcfa09066952ca6feadcdd8411ea9d","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        :param str tls_key: Path to TLS key"},{"line_number":100,"context_line":"        :param str tls_cert: Path to TLS cert"},{"line_number":101,"context_line":"        :param str tls_ca: Path to TLS CA cert"},{"line_number":102,"context_line":"        \"\"\""},{"line_number":103,"context_line":"        if self.client is None:"},{"line_number":104,"context_line":"            args \u003d dict("},{"line_number":105,"context_line":"                hosts\u003dself.hosts,"}],"source_content_type":"text/x-python","patch_set":29,"id":"e6153a47_5d705bdd","line":102,"updated":"2021-02-21 15:45:11.000000000","message":"Docstring needs to move to the connect method.  I\u0027ll fix this in a new patchset.","commit_id":"135883d5e61680305dadf15c4ba7dec80478c277"}]}
