)]}'
{"etc/providers.d/noop.conf":[{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"77cc0ef17a25d2cb70aa3996aa3c78645e65f71c","unresolved":false,"context_lines":[{"line_number":9,"context_line":"bank\u003dkarbor-swift-bank-plugin"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"[swift_client]"},{"line_number":12,"context_line":"swift_auth_url\u003dhttp://127.0.0.1:5000/v2.0/"},{"line_number":13,"context_line":"swift_auth_version\u003d2"},{"line_number":14,"context_line":"swift_user\u003dadmin"},{"line_number":15,"context_line":"swift_key\u003dpassword"}],"source_content_type":"text/plain","patch_set":19,"id":"5a74a57a_517020a4","line":12,"range":{"start_line":12,"start_character":37,"end_line":12,"end_character":41},"updated":"2016-11-29 08:53:01.000000000","message":"IMO, it should use \"v3\"","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"e75c38f5a51a428682c7a2dac1515e242b03f598","unresolved":false,"context_lines":[{"line_number":9,"context_line":"bank\u003dkarbor-swift-bank-plugin"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"[swift_client]"},{"line_number":12,"context_line":"swift_auth_url\u003dhttp://127.0.0.1:5000/v2.0/"},{"line_number":13,"context_line":"swift_auth_version\u003d2"},{"line_number":14,"context_line":"swift_user\u003dadmin"},{"line_number":15,"context_line":"swift_key\u003dpassword"}],"source_content_type":"text/plain","patch_set":19,"id":"3a71b18c_6bc2d3ea","line":12,"range":{"start_line":12,"start_character":37,"end_line":12,"end_character":41},"in_reply_to":"5a74a57a_517020a4","updated":"2016-12-11 09:09:03.000000000","message":"we\u0027ll change this in another patch, together with eisoo.conf and openstack-infra.conf","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"77cc0ef17a25d2cb70aa3996aa3c78645e65f71c","unresolved":false,"context_lines":[{"line_number":10,"context_line":""},{"line_number":11,"context_line":"[swift_client]"},{"line_number":12,"context_line":"swift_auth_url\u003dhttp://127.0.0.1:5000/v2.0/"},{"line_number":13,"context_line":"swift_auth_version\u003d2"},{"line_number":14,"context_line":"swift_user\u003dadmin"},{"line_number":15,"context_line":"swift_key\u003dpassword"},{"line_number":16,"context_line":"swift_tenant_name\u003dadmin"}],"source_content_type":"text/plain","patch_set":19,"id":"5a74a57a_716b5cb7","line":13,"range":{"start_line":13,"start_character":19,"end_line":13,"end_character":20},"updated":"2016-11-29 08:53:01.000000000","message":"3","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"e75c38f5a51a428682c7a2dac1515e242b03f598","unresolved":false,"context_lines":[{"line_number":10,"context_line":""},{"line_number":11,"context_line":"[swift_client]"},{"line_number":12,"context_line":"swift_auth_url\u003dhttp://127.0.0.1:5000/v2.0/"},{"line_number":13,"context_line":"swift_auth_version\u003d2"},{"line_number":14,"context_line":"swift_user\u003dadmin"},{"line_number":15,"context_line":"swift_key\u003dpassword"},{"line_number":16,"context_line":"swift_tenant_name\u003dadmin"}],"source_content_type":"text/plain","patch_set":19,"id":"3a71b18c_8bb3af99","line":13,"range":{"start_line":13,"start_character":19,"end_line":13,"end_character":20},"in_reply_to":"5a74a57a_716b5cb7","updated":"2016-12-11 09:09:03.000000000","message":"ditto","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"}],"karbor/api/v1/providers.py":[{"author":{"_account_id":23068,"name":"Wang Hui","email":"wanghui71@huawei.com","username":"krejwang"},"change_message_id":"07284c65fd392170334fc76843e5dbffc2e3257e","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        }"},{"line_number":393,"context_line":"        try:"},{"line_number":394,"context_line":"            checkpoint_id \u003d self.protection_api.protect(context, plan)"},{"line_number":395,"context_line":"        except Exception as error:"},{"line_number":396,"context_line":"            msg \u003d _(\"Create checkpoint failed: %s\") % error.msg"},{"line_number":397,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":398,"context_line":"        checkpoint_properties[\u0027id\u0027] \u003d checkpoint_id"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a89bdaa_55663eed","line":395,"range":{"start_line":395,"start_character":8,"end_line":395,"end_character":33},"updated":"2016-09-08 15:07:25.000000000","message":"sorry yuval, i don\u0027t get it how the exception works,does it do the same work as the former one \"if checkpoint is not None\"?","commit_id":"1d907cebf12b96def1afb63af46e5141be5796de"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"69b4617be02c62c3a43d0477c536ebd35ce62eaf","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        }"},{"line_number":393,"context_line":"        try:"},{"line_number":394,"context_line":"            checkpoint_id \u003d self.protection_api.protect(context, plan)"},{"line_number":395,"context_line":"        except Exception as error:"},{"line_number":396,"context_line":"            msg \u003d _(\"Create checkpoint failed: %s\") % error.msg"},{"line_number":397,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":398,"context_line":"        checkpoint_properties[\u0027id\u0027] \u003d checkpoint_id"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a89bdaa_dc725cb0","line":395,"range":{"start_line":395,"start_character":8,"end_line":395,"end_character":33},"in_reply_to":"9a89bdaa_55663eed","updated":"2016-09-09 01:50:26.000000000","message":"Any exceptions from \u0027self.protection_api.protect\u0027 will be caught by \u0027try..except\u0027. You can see the return value is changed, and the new \u0027protect\u0027 function becomes simpler, so there is no need to do as before.","commit_id":"1d907cebf12b96def1afb63af46e5141be5796de"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"f8659db67169ca93faa29979b1dbf819f7be24c7","unresolved":false,"context_lines":[{"line_number":388,"context_line":"            }"},{"line_number":389,"context_line":"        }"},{"line_number":390,"context_line":"        try:"},{"line_number":391,"context_line":"            checkpoint_id \u003d self.protection_api.protect(context, plan)"},{"line_number":392,"context_line":"        except Exception as error:"},{"line_number":393,"context_line":"            msg \u003d _(\"Create checkpoint failed: %s\") % error.msg"},{"line_number":394,"context_line":"            raise exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":395,"context_line":"        checkpoint_properties[\u0027id\u0027] \u003d checkpoint_id"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        returnval \u003d self._checkpoint_view_builder.detail("},{"line_number":398,"context_line":"            req, checkpoint_properties)"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_7c5eb113","line":395,"range":{"start_line":391,"start_character":0,"end_line":395,"end_character":51},"updated":"2016-11-21 07:26:09.000000000","message":"The value of resource_graph in checkpoint_properties also need be updated. So only checkpoint_id returned form protect method  is not enough.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"}],"karbor/api/v1/restores.py":[{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"2ec8484d6272aaef49af5ba087f2a1809a193631","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":"        # call restore rpc API of protection service"},{"line_number":272,"context_line":"        try:"},{"line_number":273,"context_line":"            self.protection_api.restore(context, restoreobj)"},{"line_number":274,"context_line":"        except Exception:"},{"line_number":275,"context_line":"            # update the status of restore"},{"line_number":276,"context_line":"            update_dict \u003d {"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa6399be_aebfe4fa","line":273,"range":{"start_line":273,"start_character":58,"end_line":273,"end_character":59},"updated":"2016-10-19 06:07:42.000000000","message":"It may should be self.protection_api.restore(context, restoreobj, restore_auth).","commit_id":"b38f6a91caaa1017f2c38808745cf1548f2533b8"}],"karbor/services/protection/flows/create_protection.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"b70efb4d08846fca2e788313abf868569010d1cd","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                                             parameters\u003dplan.get(\u0027parameters\u0027))"},{"line_number":43,"context_line":"    workflow_engine.add_tasks("},{"line_number":44,"context_line":"        protection_flow,"},{"line_number":45,"context_line":"        resource_flow,"},{"line_number":46,"context_line":"        CompleteProtectTask(),"},{"line_number":47,"context_line":"    )"},{"line_number":48,"context_line":"    flow_engine \u003d workflow_engine.get_engine(protection_flow, store\u003d{"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba5da102_8f4a14c4","line":45,"range":{"start_line":45,"start_character":8,"end_line":45,"end_character":21},"updated":"2016-10-31 08:29:55.000000000","message":"If the execution of resource_flow fails, the status of checkpoint has not been set to \u0027CHECKPOINT_STATUS_ERROR\u0027. \nIMO, we should check the final status of resource_flow before running the CompleteProtectTask.","commit_id":"2f88a112f2a8849593911455f7446157f3dfef1d"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"f8659db67169ca93faa29979b1dbf819f7be24c7","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class CompleteProtectTask(task.Task):"},{"line_number":24,"context_line":"    def execute(self, checkpoint):"},{"line_number":25,"context_line":"        LOG.debug(\"Complete protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":26,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_AVAILABLE"},{"line_number":27,"context_line":"        checkpoint.commit()"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def get_flow(context, workflow_engine, operation_type, plan, provider,"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_9c10edad","line":27,"range":{"start_line":24,"start_character":0,"end_line":27,"end_character":27},"updated":"2016-11-21 07:26:09.000000000","message":"As I said last time, only the normal and successful situation is considered in create_protection flow. \nThe status of checkpoint has not been set to \u0027CHECKPOINT_STATUS_ERROR\u0027 when the execution of plugins aciton in resource_flow fails or raises exceptions.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"8e6a8052affd21d71f1bf388437c8252780a5b6e","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class CompleteProtectTask(task.Task):"},{"line_number":24,"context_line":"    def execute(self, checkpoint):"},{"line_number":25,"context_line":"        LOG.debug(\"Complete protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":26,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_AVAILABLE"},{"line_number":27,"context_line":"        checkpoint.commit()"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"def get_flow(context, workflow_engine, operation_type, plan, provider,"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a74a57a_2c0d31e8","line":27,"range":{"start_line":24,"start_character":0,"end_line":27,"end_character":27},"in_reply_to":"7a77a97e_9c10edad","updated":"2016-11-28 12:21:01.000000000","message":"Thanks, will handle that.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"d42ccb069a5c28ba14ab3d68193184d067dba5e6","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_PROTECTING"},{"line_number":30,"context_line":"        checkpoint.commit()"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def revert(self, checkpoint, *args, **kwargs):"},{"line_number":33,"context_line":"        LOG.debug(\"Failed to protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":34,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_ERROR"},{"line_number":35,"context_line":"        checkpoint.commit()"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CompleteProtectTask(task.Task):"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_1fa9a47b","line":35,"range":{"start_line":32,"start_character":0,"end_line":35,"end_character":27},"updated":"2016-12-05 09:10:04.000000000","message":"In my understanding, the revert method of task will be called if there are any error or exception in this task self. Are you sure that this revert method will be called if other resources_task_flow fails?","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"f5fe73e69c76af7ce886440d8063899efcc333b3","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_PROTECTING"},{"line_number":30,"context_line":"        checkpoint.commit()"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    def revert(self, checkpoint, *args, **kwargs):"},{"line_number":33,"context_line":"        LOG.debug(\"Failed to protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":34,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_ERROR"},{"line_number":35,"context_line":"        checkpoint.commit()"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CompleteProtectTask(task.Task):"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_2b49bbb7","line":35,"range":{"start_line":32,"start_character":0,"end_line":35,"end_character":27},"in_reply_to":"3a71b18c_1fa9a47b","updated":"2016-12-11 09:06:03.000000000","message":"yes","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"}],"karbor/services/protection/flows/create_restoration.py":[{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"ccce35f5fd7496730ebabd9373fe73e07ff5e351","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def execute(self, context, heat_conf):"},{"line_number":45,"context_line":"        LOG.info(_LI(\u0027Creating Heat template. Target: \"%s\"\u0027)"},{"line_number":46,"context_line":"                 % heat_conf[\u0027auth_url\u0027])"},{"line_number":47,"context_line":"        heat_client \u003d client_factory.ClientFactory.create_client("},{"line_number":48,"context_line":"            \u0027heat\u0027, context\u003dcontext, **heat_conf)"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"9a629dbe_81ecd5c8","line":46,"range":{"start_line":46,"start_character":19,"end_line":46,"end_character":40},"updated":"2016-11-08 06:41:47.000000000","message":"If use current login tenant by default( https://review.openstack.org/#/c/385374), auth_url may not be in keys of heat_conf.","commit_id":"2209e0b5fd957cc1dfe3d8737f882c11da8bdc49"},{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"ccce35f5fd7496730ebabd9373fe73e07ff5e351","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"def get_flow(context, workflow_engine, operation_type, checkpoint, provider,"},{"line_number":110,"context_line":"             restore, restore_auth):"},{"line_number":111,"context_line":"    target \u003d restore[\u0027restore_target\u0027]"},{"line_number":112,"context_line":"    auth_type \u003d restore_auth[\"type\"]"},{"line_number":113,"context_line":"    if auth_type \u003d\u003d \"password\":"},{"line_number":114,"context_line":"        username \u003d restore_auth[\"username\"]"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a629dbe_c1a08d93","line":111,"range":{"start_line":111,"start_character":13,"end_line":111,"end_character":38},"updated":"2016-11-08 06:41:47.000000000","message":"if it doesn\u0027t specify \u0027restore_target\u0027, it should use current login tenant by default, pls refer to \nhttps://review.openstack.org/#/c/385374","commit_id":"2209e0b5fd957cc1dfe3d8737f882c11da8bdc49"},{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"dddc11d408639cc90a8b0de119dc00745b0f6ece","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def execute(self, context, heat_conf):"},{"line_number":45,"context_line":"        LOG.info(_LI(\u0027Creating Heat template. Target: \"%s\"\u0027)"},{"line_number":46,"context_line":"                 % heat_conf[\u0027auth_url\u0027])"},{"line_number":47,"context_line":"        heat_client \u003d client_factory.ClientFactory.create_client("},{"line_number":48,"context_line":"            \u0027heat\u0027, context\u003dcontext, **heat_conf)"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7a77a97e_07447972","line":46,"range":{"start_line":46,"start_character":19,"end_line":46,"end_character":40},"updated":"2016-11-15 01:33:48.000000000","message":"Maybe heat_conf.get(\u0027auth_url\u0027, None) is more appropriate.","commit_id":"77c6dfbbc7d5c4402f5dcfa8b09cf573b53eb225"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"d520fcc53c3f156163a4c49282b6c495cd2a0c9e","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def execute(self, context, heat_conf):"},{"line_number":45,"context_line":"        LOG.info(_LI(\u0027Creating Heat template. Target: \"%s\"\u0027)"},{"line_number":46,"context_line":"                 % heat_conf[\u0027auth_url\u0027])"},{"line_number":47,"context_line":"        heat_client \u003d client_factory.ClientFactory.create_client("},{"line_number":48,"context_line":"            \u0027heat\u0027, context\u003dcontext, **heat_conf)"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7a77a97e_898249ff","line":46,"range":{"start_line":46,"start_character":19,"end_line":46,"end_character":40},"in_reply_to":"7a77a97e_07447972","updated":"2016-11-15 13:22:26.000000000","message":"Yep, thanks","commit_id":"77c6dfbbc7d5c4402f5dcfa8b09cf573b53eb225"},{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"dddc11d408639cc90a8b0de119dc00745b0f6ece","unresolved":false,"context_lines":[{"line_number":111,"context_line":"    target \u003d restore.get(\u0027restore_target\u0027, None)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    heat_conf \u003d {}"},{"line_number":114,"context_line":"    if target is not None:"},{"line_number":115,"context_line":"        heat_conf[\"auth_url\"] \u003d target"},{"line_number":116,"context_line":"        if restore_auth is not None:"},{"line_number":117,"context_line":"            auth_type \u003d restore_auth.get(\"type\", None)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a77a97e_a25f330d","line":114,"range":{"start_line":114,"start_character":4,"end_line":114,"end_character":26},"updated":"2016-11-15 01:33:48.000000000","message":"Because of test_restore_create_without_target_and_auth() in test_restore, \"target\" may be not specified, you should consider it.","commit_id":"77c6dfbbc7d5c4402f5dcfa8b09cf573b53eb225"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"4151a8f70d02c47b9e3705c2c99211c0126962f9","unresolved":false,"context_lines":[{"line_number":111,"context_line":"    target \u003d restore.get(\u0027restore_target\u0027, None)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    heat_conf \u003d {}"},{"line_number":114,"context_line":"    if target is not None:"},{"line_number":115,"context_line":"        heat_conf[\"auth_url\"] \u003d target"},{"line_number":116,"context_line":"        if restore_auth is not None:"},{"line_number":117,"context_line":"            auth_type \u003d restore_auth.get(\"type\", None)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a77a97e_afe99b1c","line":114,"range":{"start_line":114,"start_character":4,"end_line":114,"end_character":26},"in_reply_to":"7a77a97e_a25f330d","updated":"2016-11-16 09:07:40.000000000","message":"heat_conf is initialized to an empty dict, so it shouldn\u0027t be a problem","commit_id":"77c6dfbbc7d5c4402f5dcfa8b09cf573b53eb225"},{"author":{"_account_id":21648,"name":"zhangshuai","email":"446077695@qq.com","username":"zhangshuai"},"change_message_id":"226f14a373e0be218d54e45abf001cf4552bfe46","unresolved":false,"context_lines":[{"line_number":111,"context_line":"    target \u003d restore.get(\u0027restore_target\u0027, None)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    heat_conf \u003d {}"},{"line_number":114,"context_line":"    if target is not None:"},{"line_number":115,"context_line":"        heat_conf[\"auth_url\"] \u003d target"},{"line_number":116,"context_line":"        if restore_auth is not None:"},{"line_number":117,"context_line":"            auth_type \u003d restore_auth.get(\"type\", None)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7a77a97e_afc7db10","line":114,"range":{"start_line":114,"start_character":4,"end_line":114,"end_character":26},"in_reply_to":"7a77a97e_afe99b1c","updated":"2016-11-16 09:17:45.000000000","message":"Got it.","commit_id":"77c6dfbbc7d5c4402f5dcfa8b09cf573b53eb225"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"06cafef7340e52fd51de7824348c58fafbaf1913","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":103,"context_line":"        super(SyncRestoreStatusTask, self).__init__(*args, **kwargs)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def execute(self, restore, stack_id, heat_client):"},{"line_number":106,"context_line":"        LOG.info(_LI(\u0027Syncing Heat stack status, stack_id: %s\u0027), stack_id)"},{"line_number":107,"context_line":"        sync_status_loop \u003d loopingcall.FixedIntervalLoopingCall("},{"line_number":108,"context_line":"            self._sync_status, restore, heat_client, stack_id)"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_b11ede09","line":105,"range":{"start_line":105,"start_character":22,"end_line":105,"end_character":29},"updated":"2016-12-16 10:13:09.000000000","message":"Maybe this task does not need \u0027restore\u0027 parameter. Because it is not used actually.","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6e13d25fcae2a979f2f5234a313254b2007c304b","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":103,"context_line":"        super(SyncRestoreStatusTask, self).__init__(*args, **kwargs)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def execute(self, restore, stack_id, heat_client):"},{"line_number":106,"context_line":"        LOG.info(_LI(\u0027Syncing Heat stack status, stack_id: %s\u0027), stack_id)"},{"line_number":107,"context_line":"        sync_status_loop \u003d loopingcall.FixedIntervalLoopingCall("},{"line_number":108,"context_line":"            self._sync_status, restore, heat_client, stack_id)"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_7f9e9a64","line":105,"range":{"start_line":105,"start_character":22,"end_line":105,"end_character":29},"in_reply_to":"1a6eadb0_42910c52","updated":"2016-12-18 15:59:26.000000000","message":"On a second look, you are correct. Removed it.","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6e79b4a7104f139e9f0e4ffc0ec9f52fd6e032ce","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":103,"context_line":"        super(SyncRestoreStatusTask, self).__init__(*args, **kwargs)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def execute(self, restore, stack_id, heat_client):"},{"line_number":106,"context_line":"        LOG.info(_LI(\u0027Syncing Heat stack status, stack_id: %s\u0027), stack_id)"},{"line_number":107,"context_line":"        sync_status_loop \u003d loopingcall.FixedIntervalLoopingCall("},{"line_number":108,"context_line":"            self._sync_status, restore, heat_client, stack_id)"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_42910c52","line":105,"range":{"start_line":105,"start_character":22,"end_line":105,"end_character":29},"in_reply_to":"1a6eadb0_b11ede09","updated":"2016-12-18 07:50:04.000000000","message":"it is used, see below","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"06cafef7340e52fd51de7824348c58fafbaf1913","unresolved":false,"context_lines":[{"line_number":160,"context_line":"    workflow_engine.add_tasks("},{"line_number":161,"context_line":"        restoration_flow,"},{"line_number":162,"context_line":"        InitiateRestoreTask(),"},{"line_number":163,"context_line":"        CreateHeatTask(inject\u003d{\u0027context\u0027: context, \u0027heat_conf\u0027: heat_conf}),"},{"line_number":164,"context_line":"        resources_task_flow,"},{"line_number":165,"context_line":"        CreateStackTask(),"},{"line_number":166,"context_line":"        SyncRestoreStatusTask(),"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_cce4a1ad","line":163,"range":{"start_line":163,"start_character":8,"end_line":163,"end_character":22},"updated":"2016-12-16 10:13:09.000000000","message":"It needs to add a \u0027providers\u003d[\u0027heat_client\u0027, \u0027heat_template\u0027]\u0027 parameter according to taskflow. Otherwise the following task can not use the output of this task which are \u0027heat_client\u0027 and \u0027heat_template\u0027.","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6e79b4a7104f139e9f0e4ffc0ec9f52fd6e032ce","unresolved":false,"context_lines":[{"line_number":160,"context_line":"    workflow_engine.add_tasks("},{"line_number":161,"context_line":"        restoration_flow,"},{"line_number":162,"context_line":"        InitiateRestoreTask(),"},{"line_number":163,"context_line":"        CreateHeatTask(inject\u003d{\u0027context\u0027: context, \u0027heat_conf\u0027: heat_conf}),"},{"line_number":164,"context_line":"        resources_task_flow,"},{"line_number":165,"context_line":"        CreateStackTask(),"},{"line_number":166,"context_line":"        SyncRestoreStatusTask(),"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_829b2472","line":163,"range":{"start_line":163,"start_character":8,"end_line":163,"end_character":22},"in_reply_to":"1a6eadb0_cce4a1ad","updated":"2016-12-18 07:50:04.000000000","message":"see \u0027default_provides\u0027 class variable","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"06cafef7340e52fd51de7824348c58fafbaf1913","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        InitiateRestoreTask(),"},{"line_number":163,"context_line":"        CreateHeatTask(inject\u003d{\u0027context\u0027: context, \u0027heat_conf\u0027: heat_conf}),"},{"line_number":164,"context_line":"        resources_task_flow,"},{"line_number":165,"context_line":"        CreateStackTask(),"},{"line_number":166,"context_line":"        SyncRestoreStatusTask(),"},{"line_number":167,"context_line":"        CompleteRestoreTask()"},{"line_number":168,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_4cb5f17b","line":165,"range":{"start_line":165,"start_character":8,"end_line":165,"end_character":23},"updated":"2016-12-16 10:13:09.000000000","message":"add a \u0027providers\u003dstack_id\u0027 parameter.","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6e79b4a7104f139e9f0e4ffc0ec9f52fd6e032ce","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        InitiateRestoreTask(),"},{"line_number":163,"context_line":"        CreateHeatTask(inject\u003d{\u0027context\u0027: context, \u0027heat_conf\u0027: heat_conf}),"},{"line_number":164,"context_line":"        resources_task_flow,"},{"line_number":165,"context_line":"        CreateStackTask(),"},{"line_number":166,"context_line":"        SyncRestoreStatusTask(),"},{"line_number":167,"context_line":"        CompleteRestoreTask()"},{"line_number":168,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_a2866014","line":165,"range":{"start_line":165,"start_character":8,"end_line":165,"end_character":23},"in_reply_to":"1a6eadb0_4cb5f17b","updated":"2016-12-18 07:50:04.000000000","message":"see \u0027default_provides\u0027 class variable","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"}],"karbor/services/protection/flows/delete_checkpoint.py":[{"author":{"_account_id":18908,"name":"shoppon","email":"shopppon@gmail.com","username":"shoppon"},"change_message_id":"818dcabf248ee66a3a8327bd265b14ce80986713","unresolved":false,"context_lines":[{"line_number":33,"context_line":"             checkpoint.id)"},{"line_number":34,"context_line":"    flow_name \u003d \"Delete_Checkpoint_\" + checkpoint.id"},{"line_number":35,"context_line":"    delete_flow \u003d workflow_engine.build_flow(flow_name, \u0027linear\u0027)"},{"line_number":36,"context_line":"    resource_graph \u003d checkpoint.resource_graph"},{"line_number":37,"context_line":"    resource_flow \u003d provider.build_task_flow(operation_type\u003doperation_type,"},{"line_number":38,"context_line":"                                             context\u003dcontext,"},{"line_number":39,"context_line":"                                             workflow_engine\u003dworkflow_engine,"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba5da102_4eb45781","line":36,"updated":"2016-11-01 12:47:09.000000000","message":"How can I delete part of checkpoints of a plan?","commit_id":"2f88a112f2a8849593911455f7446157f3dfef1d"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"f8659db67169ca93faa29979b1dbf819f7be24c7","unresolved":false,"context_lines":[{"line_number":23,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":24,"context_line":"        super(DeleteCheckpointTask, self).__init__(*args, **kwargs)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def execute(self, checkpoint):"},{"line_number":27,"context_line":"        LOG.debug(\"Start delete checkpoint task, checkpoint_id: %s\","},{"line_number":28,"context_line":"                  checkpoint.id)"},{"line_number":29,"context_line":"        checkpoint.delete()"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def get_flow(context, workflow_engine, operation_type, checkpoint, provider):"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_bc34c9fb","line":29,"range":{"start_line":26,"start_character":0,"end_line":29,"end_character":27},"updated":"2016-11-21 07:26:09.000000000","message":"If the plugin\u0027s deletion action fails in resources_task_flow, the status of checkpoint should be set \u0027CHECKPOINT_STATUS_ERROR_DELETING\u0027. I don\u0027t thin the checkpoint data also can be deteled in this situation.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"8e6a8052affd21d71f1bf388437c8252780a5b6e","unresolved":false,"context_lines":[{"line_number":23,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":24,"context_line":"        super(DeleteCheckpointTask, self).__init__(*args, **kwargs)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def execute(self, checkpoint):"},{"line_number":27,"context_line":"        LOG.debug(\"Start delete checkpoint task, checkpoint_id: %s\","},{"line_number":28,"context_line":"                  checkpoint.id)"},{"line_number":29,"context_line":"        checkpoint.delete()"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def get_flow(context, workflow_engine, operation_type, checkpoint, provider):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a74a57a_ac6a217f","line":29,"range":{"start_line":26,"start_character":0,"end_line":29,"end_character":27},"in_reply_to":"7a77a97e_bc34c9fb","updated":"2016-11-28 12:21:01.000000000","message":"Thanks, will handle that.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"}],"karbor/services/protection/flows/worker.py":[{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"b5b67ae4e68549548b03180b198e31a61cb9b424","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        engine \u003d importutils.import_object(engine_path)"},{"line_number":49,"context_line":"        return engine"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def get_flow(self, context, operation_type, **kwargs):"},{"line_number":52,"context_line":"        if operation_type \u003d\u003d constants.OPERATION_PROTECT:"},{"line_number":53,"context_line":"            plan \u003d kwargs.get(\u0027plan\u0027, None)"},{"line_number":54,"context_line":"            provider \u003d kwargs.get(\u0027provider\u0027, None)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6eadb0_81b8792c","line":51,"range":{"start_line":51,"start_character":8,"end_line":51,"end_character":16},"updated":"2016-12-19 03:12:17.000000000","message":"s/get_flow/get_protect_flow? Then it can delete the next code \u0027if operation_type \u003d\u003d constants.OPERATION_PROTECT:\u0027.","commit_id":"1ed8d60eec57666dd6ed29b0b0917b529a385062"}],"karbor/services/protection/manager.py":[{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"b5b67ae4e68549548b03180b198e31a61cb9b424","unresolved":false,"context_lines":[{"line_number":115,"context_line":"                                                   constants.OPERATION_PROTECT,"},{"line_number":116,"context_line":"                                                   plan\u003dplan,"},{"line_number":117,"context_line":"                                                   provider\u003dprovider,"},{"line_number":118,"context_line":"                                                   checkpoint\u003dcheckpoint)"},{"line_number":119,"context_line":"        except Exception as e:"},{"line_number":120,"context_line":"            LOG.exception(_LE(\"Failed to create protection flow, plan: %s\"),"},{"line_number":121,"context_line":"                          plan_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6eadb0_46daf7ea","line":118,"range":{"start_line":118,"start_character":51,"end_line":118,"end_character":72},"updated":"2016-12-19 03:12:17.000000000","message":"Good practice to create checkpoint first and use it as a parameter. I just want to know whether the reason for the new practice is that if done as before(get checkpoint id from the output of task flow), it may wait for a long time, because it can not get the output of taskflow until it finishes its work. I am confused that it should  lead to a timeout error if done as before, However, it works normally.","commit_id":"1ed8d60eec57666dd6ed29b0b0917b529a385062"}],"karbor/services/protection/protection_plugin.py":[{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":19,"context_line":"    def __init__(self):"},{"line_number":20,"context_line":"        super(Operation, self).__init__()"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    def on_prepare_begin(self, *args, **kwargs):"},{"line_number":23,"context_line":"        \"\"\"on_prepare_begin hook runs before any child resource\u0027s hooks run"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"        Optional"},{"line_number":26,"context_line":"        :param checkpoint: checkpoint object for this operation"},{"line_number":27,"context_line":"        :param resource: a resource object for this operation"},{"line_number":28,"context_line":"        :param context: current operation context (viable for clients)"},{"line_number":29,"context_line":"        :param parameter: dictionary representing operation parameters"},{"line_number":30,"context_line":"        :param heat_template: HeatTemplate for restore operation only"},{"line_number":31,"context_line":"        \"\"\""},{"line_number":32,"context_line":"        pass"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def on_prepare_finish(self, *args, **kwargs):"},{"line_number":35,"context_line":"        \"\"\"on_prepare_finish hook runs after all child resources\u0027 prepare hooks"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_e4a9317d","line":32,"range":{"start_line":22,"start_character":0,"end_line":32,"end_character":12},"updated":"2016-12-19 10:17:18.000000000","message":"Why aren\u0027t these part of the signature?","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"}],"karbor/services/protection/protection_plugins/base_protection_plugin.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"d42ccb069a5c28ba14ab3d68193184d067dba5e6","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            constants.OPERATION_DELETE: self.delete_backup"},{"line_number":29,"context_line":"        }"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    @abc.abstractmethod"},{"line_number":32,"context_line":"    def create_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":33,"context_line":"        pass"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def restore_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":37,"context_line":"        pass"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    @abc.abstractmethod"},{"line_number":40,"context_line":"    def delete_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":41,"context_line":"        pass"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def on_resource_start(self, context):"},{"line_number":44,"context_line":"        task \u003d None"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_df1f2c06","line":41,"range":{"start_line":31,"start_character":0,"end_line":41,"end_character":12},"updated":"2016-12-05 09:10:04.000000000","message":"IMO, these methods definition should been reserved. They are easy to understand for vendors. By default, other needless hooks could not been exposed to vendors.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"834c8937f41d1e4005e870813d6fe6ab5e12494b","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            constants.OPERATION_DELETE: self.delete_backup"},{"line_number":29,"context_line":"        }"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    @abc.abstractmethod"},{"line_number":32,"context_line":"    def create_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":33,"context_line":"        pass"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def restore_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":37,"context_line":"        pass"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    @abc.abstractmethod"},{"line_number":40,"context_line":"    def delete_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":41,"context_line":"        pass"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def on_resource_start(self, context):"},{"line_number":44,"context_line":"        task \u003d None"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_c2957ae4","line":41,"range":{"start_line":31,"start_character":0,"end_line":41,"end_character":12},"in_reply_to":"3a71b18c_aba14b48","updated":"2016-12-12 07:19:16.000000000","message":"@yuval Sorry, \"needless hooks\" is not suitable.  I means that vendor EISOO has developed its protection plugin basing on current south bound interfaces. If the interfaces of plugins all have been changed, it means that the plugins also need been refactored.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"089befa7490f6d3afe22f9d86ef3d6c68abf8fb3","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            constants.OPERATION_DELETE: self.delete_backup"},{"line_number":29,"context_line":"        }"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    @abc.abstractmethod"},{"line_number":32,"context_line":"    def create_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":33,"context_line":"        pass"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def restore_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":37,"context_line":"        pass"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    @abc.abstractmethod"},{"line_number":40,"context_line":"    def delete_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":41,"context_line":"        pass"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def on_resource_start(self, context):"},{"line_number":44,"context_line":"        task \u003d None"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_0f731a81","line":41,"range":{"start_line":31,"start_character":0,"end_line":41,"end_character":12},"in_reply_to":"3a71b18c_c2957ae4","updated":"2016-12-12 08:11:22.000000000","message":"I agree that this is inconvenient, but since `get_resource_stats` is removed and each method needs to be synchronous, that protection plugin will have to be refactored anyway.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"f5fe73e69c76af7ce886440d8063899efcc333b3","unresolved":false,"context_lines":[{"line_number":28,"context_line":"            constants.OPERATION_DELETE: self.delete_backup"},{"line_number":29,"context_line":"        }"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    @abc.abstractmethod"},{"line_number":32,"context_line":"    def create_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":33,"context_line":"        pass"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def restore_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":37,"context_line":"        pass"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    @abc.abstractmethod"},{"line_number":40,"context_line":"    def delete_backup(self, cntxt, checkpoint, **kwargs):"},{"line_number":41,"context_line":"        pass"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def on_resource_start(self, context):"},{"line_number":44,"context_line":"        task \u003d None"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_aba14b48","line":41,"range":{"start_line":31,"start_character":0,"end_line":41,"end_character":12},"in_reply_to":"3a71b18c_df1f2c06","updated":"2016-12-11 09:06:03.000000000","message":"1. \"needless hooks\"? I believe that we already discussed that, and that some vendors will have to use these hooks.\n2. This whole interface of \u0027BaseProtectionPlugin\u0027 is not needed in my opinion. The exact same thing can be done easily with the ProtectionPlugin interface\n3. Current protection plugins (cinder, nova, etc) implement their work asynchronously, while polling using `get_resource_stats`. This is not the way to go now","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"}],"karbor/services/protection/resource_flow.py":[{"author":{"_account_id":15069,"name":"zhonghuali","email":"lizhonghua.li@huawei.com","username":"sloblee"},"change_message_id":"fe0a7db45e18534d9faef54ca937adda055f9ac0","unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def _create_activity_task(self, plugin, resource, activity_type):"},{"line_number":131,"context_line":"        assert(activity_type in ACTIVITY_TYPES)"},{"line_number":132,"context_line":"        method_name \u003d \u0027activity_{}_{}\u0027.format(self.operation_type,"},{"line_number":133,"context_line":"                                              activity_type)"},{"line_number":134,"context_line":"        method \u003d None"},{"line_number":135,"context_line":"        if hasattr(plugin, method_name):"},{"line_number":136,"context_line":"            LOG.debug(\"found method %s\", method_name)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a89bdaa_591a876f","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":60},"updated":"2016-09-06 12:25:59.000000000","message":"it was really a good implementation to automatically find and execute the southern API from the plug-ins. but is the method name as \"activity_protect_parallel\" too unreadable for the developers who plan to create one plugin which extends from the ProtectionPlugin?\nif I am the developer,then I plan to implement one plugin, I would prefer to see the business interface more significative as:\n\"create_backup\", \"restore\"...","commit_id":"1d907cebf12b96def1afb63af46e5141be5796de"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"7a288788e1e73786664d4e45ddb678dd841d24e1","unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def _create_activity_task(self, plugin, resource, activity_type):"},{"line_number":131,"context_line":"        assert(activity_type in ACTIVITY_TYPES)"},{"line_number":132,"context_line":"        method_name \u003d \u0027activity_{}_{}\u0027.format(self.operation_type,"},{"line_number":133,"context_line":"                                              activity_type)"},{"line_number":134,"context_line":"        method \u003d None"},{"line_number":135,"context_line":"        if hasattr(plugin, method_name):"},{"line_number":136,"context_line":"            LOG.debug(\"found method %s\", method_name)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a89bdaa_6e3f5a87","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":60},"in_reply_to":"9a89bdaa_591a876f","updated":"2016-09-07 03:42:47.000000000","message":"@zhonghuali, for example, in the heat, resource plugins, such as nova, will extend the base class to implement its own method, such as \u0027handle_create\u0027, \u0027check_create_complete\u0027, but in the base class, the methods are like \u0027create\u0027, \u0027delete\u0027. They are the same ideas. If developers understand the design of plugin, they will not be confused.","commit_id":"1d907cebf12b96def1afb63af46e5141be5796de"},{"author":{"_account_id":15069,"name":"zhonghuali","email":"lizhonghua.li@huawei.com","username":"sloblee"},"change_message_id":"2e3bbec4fdcffa95bff4304b1f18109bce3bcf9b","unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def _create_activity_task(self, plugin, resource, activity_type):"},{"line_number":131,"context_line":"        assert(activity_type in ACTIVITY_TYPES)"},{"line_number":132,"context_line":"        method_name \u003d \u0027activity_{}_{}\u0027.format(self.operation_type,"},{"line_number":133,"context_line":"                                              activity_type)"},{"line_number":134,"context_line":"        method \u003d None"},{"line_number":135,"context_line":"        if hasattr(plugin, method_name):"},{"line_number":136,"context_line":"            LOG.debug(\"found method %s\", method_name)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9a89bdaa_a19df00b","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":60},"in_reply_to":"9a89bdaa_6e3f5a87","updated":"2016-09-07 07:38:51.000000000","message":"I think they are different,I can understand the meaning of all that you list,I also think it\u0027s ok from the technical sight,but please consider the 3rd vendors, could you explain them what\u0027s the real meaning of \"activity_protect_parallel\" for 3rd developer only from the name? I promise they will ask you which API should be implemented.","commit_id":"1d907cebf12b96def1afb63af46e5141be5796de"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"a17bc9cfae2d57cc556fed71decf74c7e5c1bf94","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                           child_hooks.pre_begin)"},{"line_number":162,"context_line":"            self.workflow_engine.link_task(self.flow, child_hooks.pre_finish,"},{"line_number":163,"context_line":"                                           parent_hooks.pre_finish)"},{"line_number":164,"context_line":"            self.workflow_engine.link_task(self.flow, child_hooks.complete,"},{"line_number":165,"context_line":"                                           parent_hooks.complete)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5a74a57a_666033d0","line":164,"updated":"2016-11-28 08:21:26.000000000","message":"My question is about the parallelism of the full protection work flow.  I can see the work flow is customized for the \u0027full server\u0027 backup, where server first freeze IO, flush IO, then server and volumes could take snapshot to ensure the consistency, at last server thaws to allow both server and volumes to uploading/transmitting their backup data.\n \nThis is good for server/volume parent/children relationship.  However, for image and network, who actually doesn\u0027t have the IO issue, which are composed with a null operation of pre_begin, pre_finish, and complete, they still have to link the null operation in workflow and thus wait for IO freeze/flush/thaw operations.\n\nAny idea not to link to the operation if it\u0027s null?  So we could make those simple plugins work on parallel with main operation only.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6874ccfa05364007644a4aae9b5915d7bd10cf86","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                           child_hooks.pre_begin)"},{"line_number":162,"context_line":"            self.workflow_engine.link_task(self.flow, child_hooks.pre_finish,"},{"line_number":163,"context_line":"                                           parent_hooks.pre_finish)"},{"line_number":164,"context_line":"            self.workflow_engine.link_task(self.flow, child_hooks.complete,"},{"line_number":165,"context_line":"                                           parent_hooks.complete)"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5a74a57a_8c4ac524","line":164,"in_reply_to":"5a74a57a_666033d0","updated":"2016-11-28 12:13:25.000000000","message":"Avoiding using noop/null operations is possible, but not desirable. They have almost zero cost, they make building the task graph much more intuitively, and help printing to the logs what exactly happened for debug.\n\nIf I understand your question correctly - why should network main hook wait until a server quiesces? The answer is that the server defines which operations are required to happen before any of it\u0027s dependent resources, regardless of their type.\nThe hooks are there to help protection plugins define which operation happen in relation to dependent resources operations.\nSo yes, if a server defines a \u0027quiesce\u0027 operation in its prepeare_begin hook, network protect will have to wait for it.","commit_id":"a687e3b4b7a4ebf0476b695f2a0bcce7b08e38f5"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"d42ccb069a5c28ba14ab3d68193184d067dba5e6","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            method \u003d getattr(operation_obj, hook_type)"},{"line_number":93,"context_line":"            assert(callable(method))"},{"line_number":94,"context_line":"        else:"},{"line_number":95,"context_line":"            LOG.debug(\"found no method %s, adding noop\", hook_type)"},{"line_number":96,"context_line":"            method \u003d noop_handle"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"        task_name \u003d \"{operation_type}_{hook_type}_{type}_{id}\".format("},{"line_number":99,"context_line":"            type\u003dresource.type,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_e4f0df93","line":96,"range":{"start_line":95,"start_character":0,"end_line":96,"end_character":32},"updated":"2016-12-05 09:10:04.000000000","message":"If the vendor\u0027s plugins only implement on_mian hook, the task about other unimplemented hooks could be null. It doesn\u0027t need  return a task containing noop_handle method to ResourceHooks. If there are so many noop_handle task in the resources_flow, there will be a loss of performance more or less.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"f5fe73e69c76af7ce886440d8063899efcc333b3","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            method \u003d getattr(operation_obj, hook_type)"},{"line_number":93,"context_line":"            assert(callable(method))"},{"line_number":94,"context_line":"        else:"},{"line_number":95,"context_line":"            LOG.debug(\"found no method %s, adding noop\", hook_type)"},{"line_number":96,"context_line":"            method \u003d noop_handle"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"        task_name \u003d \"{operation_type}_{hook_type}_{type}_{id}\".format("},{"line_number":99,"context_line":"            type\u003dresource.type,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_6bcd7330","line":96,"range":{"start_line":95,"start_character":0,"end_line":96,"end_character":32},"in_reply_to":"3a71b18c_e4f0df93","updated":"2016-12-11 09:06:03.000000000","message":"1. noop methods will not impact performance that much.\n2. noop methods are important for maintaining the links between tasks correctly.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"06cafef7340e52fd51de7824348c58fafbaf1913","unresolved":false,"context_lines":[{"line_number":179,"context_line":"def build_resource_flow(operation_type, context, workflow_engine,"},{"line_number":180,"context_line":"                        plugins, resource_graph, parameters):"},{"line_number":181,"context_line":"    LOG.info(_LI(\"Build resource flow for operation %s\"), operation_type)"},{"line_number":182,"context_line":"    resource_flow \u003d workflow_engine.build_flow(\u0027ResourceFlow\u0027, \u0027linear\u0027)"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    resource_graph_flow \u003d workflow_engine.build_flow("},{"line_number":185,"context_line":"        \u0027ResourceGraphFlow_{}\u0027.format(operation_type),"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_80b8b276","line":182,"range":{"start_line":182,"start_character":4,"end_line":182,"end_character":17},"updated":"2016-12-16 10:13:09.000000000","message":"Sorry, not quite understand. Why re-create a linear flow? Why not return the \u0027resource_graph_flow\u0027 directly?","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"6e79b4a7104f139e9f0e4ffc0ec9f52fd6e032ce","unresolved":false,"context_lines":[{"line_number":179,"context_line":"def build_resource_flow(operation_type, context, workflow_engine,"},{"line_number":180,"context_line":"                        plugins, resource_graph, parameters):"},{"line_number":181,"context_line":"    LOG.info(_LI(\"Build resource flow for operation %s\"), operation_type)"},{"line_number":182,"context_line":"    resource_flow \u003d workflow_engine.build_flow(\u0027ResourceFlow\u0027, \u0027linear\u0027)"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    resource_graph_flow \u003d workflow_engine.build_flow("},{"line_number":185,"context_line":"        \u0027ResourceGraphFlow_{}\u0027.format(operation_type),"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_c2151c9c","line":182,"range":{"start_line":182,"start_character":4,"end_line":182,"end_character":17},"in_reply_to":"1a6eadb0_80b8b276","updated":"2016-12-18 07:50:04.000000000","message":"Thanks for pointing that out, fixed in next patch-set","commit_id":"a08f1e2e3d21fdc97f28304edd875eb096ca9749"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        super(ResourceFlowGraphWalkerListener, self).__init__()"},{"line_number":65,"context_line":"        self.operation_type \u003d operation_type"},{"line_number":66,"context_line":"        self.context \u003d context"},{"line_number":67,"context_line":"        self.parameters \u003d parameters"},{"line_number":68,"context_line":"        self.plugins \u003d plugins"},{"line_number":69,"context_line":"        self.workflow_engine \u003d workflow_engine"},{"line_number":70,"context_line":"        self.flow \u003d resource_flow"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_67e1a3fe","line":67,"range":{"start_line":67,"start_character":26,"end_line":67,"end_character":36},"updated":"2016-12-19 10:17:18.000000000","message":"parameters or {}\n\nThis way you know you always have a valid dict in self.parameters\n\nIn general try and avoid having None laying about where default values could suffice.","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":87,"context_line":"                             post_task)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def _create_hook_task(self, operation_obj, resource, hook_type):"},{"line_number":90,"context_line":"        if hasattr(operation_obj, hook_type):"},{"line_number":91,"context_line":"            LOG.debug(\"found method %s\", hook_type)"},{"line_number":92,"context_line":"            method \u003d getattr(operation_obj, hook_type)"},{"line_number":93,"context_line":"            assert(callable(method))"},{"line_number":94,"context_line":"        else:"},{"line_number":95,"context_line":"            LOG.debug(\"found no method %s, adding noop\", hook_type)"},{"line_number":96,"context_line":"            method \u003d noop_handle"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"        task_name \u003d \"{operation_type}_{hook_type}_{type}_{id}\".format("},{"line_number":99,"context_line":"            type\u003dresource.type,"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_6713630e","line":96,"range":{"start_line":90,"start_character":8,"end_line":96,"end_character":32},"updated":"2016-12-19 10:17:18.000000000","message":"method \u003d getattr(operation_obj, hook_type, noop_handle)\nassert callable(method), \"Got a non callable hook for %s.%s\" % (operation_obj.__type__, hook_type)","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            operation_type\u003dself.operation_type,"},{"line_number":103,"context_line":"        )"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        if self.parameters:"},{"line_number":106,"context_line":"            parameters \u003d self.parameters.get(resource.type, {})"},{"line_number":107,"context_line":"            resource_id \u003d \u0027{}#{}\u0027.format(resource.type, resource.id)"},{"line_number":108,"context_line":"            parameters.update(self.parameters.get(resource_id, {}))"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_07b9cfec","line":105,"range":{"start_line":105,"start_character":8,"end_line":105,"end_character":27},"updated":"2016-12-19 10:17:18.000000000","message":"given the comment in 67 this branch can be eliminated","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        if self.parameters:"},{"line_number":106,"context_line":"            parameters \u003d self.parameters.get(resource.type, {})"},{"line_number":107,"context_line":"            resource_id \u003d \u0027{}#{}\u0027.format(resource.type, resource.id)"},{"line_number":108,"context_line":"            parameters.update(self.parameters.get(resource_id, {}))"},{"line_number":109,"context_line":"        else:"},{"line_number":110,"context_line":"            parameters \u003d {}"},{"line_number":111,"context_line":"        injects \u003d {"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_e79bf370","line":108,"range":{"start_line":108,"start_character":12,"end_line":108,"end_character":29},"updated":"2016-12-19 10:17:18.000000000","message":"If you actually got a result from self.parameters.get() instead of the default, this will update the type parameters and all subsequent instances of the same type will contain the parameters of the specific instance.\n\nchange line 106 to:\n parameters \u003d self.parameters.get(resource.type, {}).copy()\n\nso that this doesn\u0027t happen.","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":114,"context_line":"            \u0027resource\u0027: resource,"},{"line_number":115,"context_line":"        }"},{"line_number":116,"context_line":"        requires \u003d list(injects)"},{"line_number":117,"context_line":"        requires.extend([\u0027checkpoint\u0027, ])"},{"line_number":118,"context_line":"        requires.extend(OPERATION_EXTRA_ARGS.get(self.operation_type, []))"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"        task \u003d self.workflow_engine.create_task(method,"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_e745b3b3","line":117,"range":{"start_line":117,"start_character":8,"end_line":117,"end_character":41},"updated":"2016-12-19 10:17:18.000000000","message":"requires.append(\u0027checkpoint\u0027)","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"b5620ee9f3e236778dd6d6daffa498d57dd54abd","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        protection_plugin \u003d self.plugins[resource.type]"},{"line_number":142,"context_line":"        operation_getter_name \u003d \u0027get_{}_operation\u0027.format(self.operation_type)"},{"line_number":143,"context_line":"        operation_getter \u003d getattr(protection_plugin, operation_getter_name)"},{"line_number":144,"context_line":"        assert(callable(operation_getter))"},{"line_number":145,"context_line":"        operation_obj \u003d operation_getter(resource)"},{"line_number":146,"context_line":"        hooks \u003d self._create_hook_tasks(operation_obj, resource)"},{"line_number":147,"context_line":"        LOG.debug(\"added operation %s hooks\", self.operation_type)"}],"source_content_type":"text/x-python","patch_set":23,"id":"1a6eadb0_87da3fe8","line":144,"range":{"start_line":144,"start_character":8,"end_line":144,"end_character":42},"updated":"2016-12-19 10:17:18.000000000","message":"assert is a statement not a function[1].\n assert callable(operation_getter)\n\n[1] https://docs.python.org/3/reference/simple_stmts.html#grammar-token-assert_stmt","commit_id":"abed54b46cfb83293764fafcffe6916d86686559"}],"karbor/tests/fullstack/test_checkpoints.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"d42ccb069a5c28ba14ab3d68193184d067dba5e6","unresolved":false,"context_lines":[{"line_number":22,"context_line":"        self.provider_id \u003d self.provider_id_noop"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def test_checkpoint_create(self):"},{"line_number":25,"context_line":"        self.skipTest(\u0027Requires cinder protection plugin adjustment\u0027)"},{"line_number":26,"context_line":"        volume \u003d self.store(objects.Volume())"},{"line_number":27,"context_line":"        volume.create(1)"},{"line_number":28,"context_line":"        plan \u003d self.store(objects.Plan())"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_9f7054de","line":25,"range":{"start_line":25,"start_character":8,"end_line":25,"end_character":69},"updated":"2016-12-05 09:10:04.000000000","message":"I don\u0027t think skip the fullstack test is a good idea, It is confused that with default plugins all protect/delete/restore function are ok in this patch. The jinkens could be in failed status before that all the work about this patch have not been finished.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"f5fe73e69c76af7ce886440d8063899efcc333b3","unresolved":false,"context_lines":[{"line_number":22,"context_line":"        self.provider_id \u003d self.provider_id_noop"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def test_checkpoint_create(self):"},{"line_number":25,"context_line":"        self.skipTest(\u0027Requires cinder protection plugin adjustment\u0027)"},{"line_number":26,"context_line":"        volume \u003d self.store(objects.Volume())"},{"line_number":27,"context_line":"        volume.create(1)"},{"line_number":28,"context_line":"        plan \u003d self.store(objects.Plan())"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_abd30bd4","line":25,"range":{"start_line":25,"start_character":8,"end_line":25,"end_character":69},"in_reply_to":"3a71b18c_9f7054de","updated":"2016-12-11 09:06:03.000000000","message":"all the work on this patch is complete.\nThis is the only test which cannot use a noop provider, since it actually tests for the outcome of a concrete provider (OS infra).\nThis test will be available once the protection plugin adjustments are merged in later patches.","commit_id":"23c29732bf9adc2a9dc42730749acff2f66e0bf5"}],"smaug/api/v1/providers.py":[{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"63d0ab9215d80b98c9916278d35fabe8e8572a65","unresolved":false,"context_lines":[{"line_number":391,"context_line":"            }"},{"line_number":392,"context_line":"        }"},{"line_number":393,"context_line":"        checkpoint_id \u003d self.protection_api.protect(context, plan)"},{"line_number":394,"context_line":"        if checkpoint is None:"},{"line_number":395,"context_line":"            msg \u003d _(\"Create checkpoint failed.\")"},{"line_number":396,"context_line":"            raise exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":397,"context_line":"        checkpoint_properties[\u0027id\u0027] \u003d checkpoint_id"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_466a43b4","line":394,"range":{"start_line":394,"start_character":8,"end_line":394,"end_character":30},"updated":"2016-08-11 03:26:46.000000000","message":"s/checkpoint/checkpoint_id ? checkpoint should not be None.","commit_id":"1003395a00d859026b017d902d38f5da73d10b43"},{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"63d0ab9215d80b98c9916278d35fabe8e8572a65","unresolved":false,"context_lines":[{"line_number":391,"context_line":"            }"},{"line_number":392,"context_line":"        }"},{"line_number":393,"context_line":"        checkpoint_id \u003d self.protection_api.protect(context, plan)"},{"line_number":394,"context_line":"        if checkpoint is None:"},{"line_number":395,"context_line":"            msg \u003d _(\"Create checkpoint failed.\")"},{"line_number":396,"context_line":"            raise exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":397,"context_line":"        checkpoint_properties[\u0027id\u0027] \u003d checkpoint_id"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"        returnval \u003d self._checkpoint_view_builder.detail("}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_060debe7","line":396,"range":{"start_line":394,"start_character":0,"end_line":396,"end_character":51},"updated":"2016-08-11 03:26:46.000000000","message":"In my opinion, you should use \u0027try .. except\u0027 to catch the exception from \u0027self.protection_api.protect\u0027, and convert it to \u0027HTTPError\u0027 like exception, such as \u0027HTTPBadRequest\u0027 etc.","commit_id":"1003395a00d859026b017d902d38f5da73d10b43"}],"smaug/api/v1/restores.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"0ab506709466f7d9a425d59e9dc6d92390b0e8bf","unresolved":false,"context_lines":[{"line_number":272,"context_line":"            check_policy(context, \u0027update\u0027, restoreobj)"},{"line_number":273,"context_line":"            restoreobj.update(update_dict)"},{"line_number":274,"context_line":"            restoreobj.save()"},{"line_number":275,"context_line":"            raise"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        retval \u003d self._view_builder.detail(req, restoreobj)"},{"line_number":278,"context_line":"        return retval"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_469d1509","line":275,"range":{"start_line":275,"start_character":12,"end_line":275,"end_character":17},"updated":"2016-08-01 10:05:14.000000000","message":"Consider raising a new HTTPException with a error code.","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"}],"smaug/common/constants.py":[{"author":{"_account_id":23020,"name":"yizhihui","email":"yi.zhihui@eisoo.com","username":"yizhihui"},"change_message_id":"7f746fafeb5a1516d2a1774c3bc7a07d35490697","unresolved":false,"context_lines":[{"line_number":71,"context_line":"OPERATION_EXE_STATE_SUCCESS \u003d \u0027success\u0027"},{"line_number":72,"context_line":"OPERATION_EXE_STATE_FAILED \u003d \u0027failed\u0027"},{"line_number":73,"context_line":"OPERATION_EXE_STATE_DROPPED_OUT_OF_WINDOW \u003d \u0027dropped_out_of_window\u0027"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"RESTORE_STATUS_SUCCESS \u003d \u0027success\u0027"},{"line_number":76,"context_line":"RESTORE_STATUS_FAILURE \u003d \u0027fail\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"bacf61ea_a6269ccb","line":76,"range":{"start_line":74,"start_character":0,"end_line":76,"end_character":31},"updated":"2016-08-05 09:44:19.000000000","message":"Maybe RESTORE_STATE_SUCCESS and RESTORE_STATE_FAILURE are better.","commit_id":"eedfbdba34376d044d43f6ec1ecc24f16fbf5c7c"}],"smaug/services/protection/flows/create_protection.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"0ab506709466f7d9a425d59e9dc6d92390b0e8bf","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":40,"context_line":"        super(CompleteProtectTask, self).__init__(*args, **kwargs)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def execute(self, checkpoint):"},{"line_number":43,"context_line":"        LOG.debug(\"Complete protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":44,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_AVAILABLE"},{"line_number":45,"context_line":"        checkpoint.commit()"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_5aae8f81","line":42,"range":{"start_line":42,"start_character":0,"end_line":42,"end_character":34},"updated":"2016-08-01 10:05:14.000000000","message":"Do you mean that we don\u0027t need sync checkpoint status from the status of resources in the checkpoint data?","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"066c2364986389014ae9a8ea7b4df74b7761b446","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":40,"context_line":"        super(CompleteProtectTask, self).__init__(*args, **kwargs)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def execute(self, checkpoint):"},{"line_number":43,"context_line":"        LOG.debug(\"Complete protect checkpoint_id: %s\", checkpoint.id)"},{"line_number":44,"context_line":"        checkpoint.status \u003d constants.CHECKPOINT_STATUS_AVAILABLE"},{"line_number":45,"context_line":"        checkpoint.commit()"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_2621d39e","line":42,"range":{"start_line":42,"start_character":0,"end_line":42,"end_character":34},"in_reply_to":"bacf61ea_5aae8f81","updated":"2016-08-07 02:30:00.000000000","message":"As Yuval\u0027s new design, the plugin will yield a generator whose status will be checked in the workflow framework.  So this won\u0027t be a problem here.","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"}],"smaug/services/protection/flows/create_restoration.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"0ab506709466f7d9a425d59e9dc6d92390b0e8bf","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                return"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            if stack_status \u003d\u003d \u0027COMPLETE\u0027:"},{"line_number":88,"context_line":"                restore.status \u003d \u0027success\u0027"},{"line_number":89,"context_line":"            else:"},{"line_number":90,"context_line":"                restore.status \u003d \u0027failed\u0027"},{"line_number":91,"context_line":"            restore.save()"},{"line_number":92,"context_line":"            raise loopingcall.LoopingCallDone()"},{"line_number":93,"context_line":"        except Exception as err:"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_157b48f6","line":90,"range":{"start_line":88,"start_character":0,"end_line":90,"end_character":41},"updated":"2016-08-01 10:05:14.000000000","message":"It is better to define all the status of restore in the module smaug.common.constants .","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"}],"smaug/services/protection/flows/delete_checkpoint.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"0ab506709466f7d9a425d59e9dc6d92390b0e8bf","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    def execute(self, checkpoint):"},{"line_number":27,"context_line":"        LOG.debug(\"Start delete checkpoint task, checkpoint_id: %s\","},{"line_number":28,"context_line":"                  checkpoint.id)"},{"line_number":29,"context_line":"        checkpoint.delete()"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def get_flow(context, workflow_engine, operation_type, checkpoint, provider):"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_1c7fec66","line":29,"range":{"start_line":29,"start_character":8,"end_line":29,"end_character":27},"updated":"2016-08-01 10:05:14.000000000","message":"If checkpoint is deleted actually here, we cann\u0027t get the  history log/record for deletion aciton.","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"}],"smaug/services/protection/manager.py":[{"author":{"_account_id":18266,"name":"zengchen","email":"chenzeng2@huawei.com","username":"zengchen"},"change_message_id":"63d0ab9215d80b98c9916278d35fabe8e8572a65","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        self.protectable_registry \u003d ProtectableRegistry()"},{"line_number":63,"context_line":"        self.protectable_registry.load_plugins()"},{"line_number":64,"context_line":"        self.worker \u003d flow_manager.Worker()"},{"line_number":65,"context_line":"        self._greenpool \u003d greenpool.GreenPool()"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def init_host(self, **kwargs):"},{"line_number":68,"context_line":"        \"\"\"Handle initialization if this is a standalone service\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_68dbd14f","line":65,"range":{"start_line":65,"start_character":8,"end_line":65,"end_character":47},"updated":"2016-08-11 03:26:46.000000000","message":"The default thread number for an instance of GreenPool is 1000, how about if the threads are exhausted.","commit_id":"1003395a00d859026b017d902d38f5da73d10b43"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"7e36fca1a3eb68c63883b0fa840460c91fdc92b5","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                          plan_id)"},{"line_number":98,"context_line":"            raise exception.FlowError("},{"line_number":99,"context_line":"                flow\u003d\"protect\","},{"line_number":100,"context_line":"                error\u003de.msg)"},{"line_number":101,"context_line":"        try:"},{"line_number":102,"context_line":"            protection_flow \u003d self.worker.get_flow(context,"},{"line_number":103,"context_line":"                                                   constants.OPERATION_PROTECT,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_0b041a48","line":100,"range":{"start_line":100,"start_character":16,"end_line":100,"end_character":28},"updated":"2016-08-16 16:00:57.000000000","message":"You should chain the original exception so that it can be recovered\\logged.\n\nhttps://docs.python.org/3/reference/simple_stmts.html#the-raise-statement","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"c6cab9ec3b23672bc4d3ddcd37af4e0dc4ce8ecc","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                          plan_id)"},{"line_number":98,"context_line":"            raise exception.FlowError("},{"line_number":99,"context_line":"                flow\u003d\"protect\","},{"line_number":100,"context_line":"                error\u003de.msg)"},{"line_number":101,"context_line":"        try:"},{"line_number":102,"context_line":"            protection_flow \u003d self.worker.get_flow(context,"},{"line_number":103,"context_line":"                                                   constants.OPERATION_PROTECT,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_521fafb6","line":100,"range":{"start_line":100,"start_character":16,"end_line":100,"end_character":28},"in_reply_to":"3ac371cc_0b041a48","updated":"2016-08-17 12:53:16.000000000","message":"Exception chaining not supported on python 2. Will use six.raise_from","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"}],"smaug/services/protection/resource_flow.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"0ab506709466f7d9a425d59e9dc6d92390b0e8bf","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        requires\u003d[\u0027barrier\u0027],"},{"line_number":218,"context_line":"    )"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    resource_graph_flow \u003d workflow_engine.build_flow(\u0027ResourceGraphFlow\u0027,"},{"line_number":221,"context_line":"                                                     \u0027graph\u0027)"},{"line_number":222,"context_line":"    resource_walker \u003d ResourceFlowGraphWalkerListener(resource_graph_flow,"},{"line_number":223,"context_line":"                                                      operation_type,"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_1b4ff96b","line":220,"range":{"start_line":220,"start_character":54,"end_line":220,"end_character":71},"updated":"2016-08-01 10:05:14.000000000","message":"all the resource flows have the same flow_name. Can we distinguish the flows by name with different operation_type or id? like \u0027ResourceGraphFlow\u0027 + operation_type","commit_id":"8ee7363a2448352730da2dee16578ff52f717c2d"},{"author":{"_account_id":23020,"name":"yizhihui","email":"yi.zhihui@eisoo.com","username":"yizhihui"},"change_message_id":"7f746fafeb5a1516d2a1774c3bc7a07d35490697","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"CONF.register_opts(resource_flow_opts)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"ACTIVITY_TYPES \u003d ("},{"line_number":37,"context_line":"    ACTIVITY_TYPE_PRE,"},{"line_number":38,"context_line":"    ACTIVITY_TYPE_PARALLEL,"},{"line_number":39,"context_line":"    ACTIVITY_TYPE_POST,"},{"line_number":40,"context_line":") \u003d ("},{"line_number":41,"context_line":"    \u0027pre\u0027,"},{"line_number":42,"context_line":"    \u0027parallel\u0027,"},{"line_number":43,"context_line":"    \u0027post\u0027,"},{"line_number":44,"context_line":")"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"ResourceActivities \u003d namedtuple(\u0027ResourceActivities\u0027, ["}],"source_content_type":"text/x-python","patch_set":3,"id":"bacf61ea_4c2261a4","line":44,"range":{"start_line":35,"start_character":0,"end_line":44,"end_character":1},"updated":"2016-08-05 09:44:19.000000000","message":"Whether this definition could be moved to constants.py?","commit_id":"eedfbdba34376d044d43f6ec1ecc24f16fbf5c7c"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"7e36fca1a3eb68c63883b0fa840460c91fdc92b5","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def _GeneratorTaskWrap(activity, barrier, *args, **kwargs):"},{"line_number":52,"context_line":"    ret \u003d activity(*args, **kwargs)"},{"line_number":53,"context_line":"    if not isinstance(ret, types.GeneratorType):"},{"line_number":54,"context_line":"        return ret"},{"line_number":55,"context_line":"    else:"},{"line_number":56,"context_line":"        activity \u003d ret"},{"line_number":57,"context_line":"        ret \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_86063fcc","line":54,"range":{"start_line":53,"start_character":4,"end_line":54,"end_character":18},"updated":"2016-08-16 16:00:57.000000000","message":"I might be missing something. Why aren\u0027t we checking if it\u0027s iterable using iter() instead of manually type checking?\n\nThat way we can support regular iterators for cases where someone wants to implement the loop through the iterator interface?","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"c6cab9ec3b23672bc4d3ddcd37af4e0dc4ce8ecc","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def _GeneratorTaskWrap(activity, barrier, *args, **kwargs):"},{"line_number":52,"context_line":"    ret \u003d activity(*args, **kwargs)"},{"line_number":53,"context_line":"    if not isinstance(ret, types.GeneratorType):"},{"line_number":54,"context_line":"        return ret"},{"line_number":55,"context_line":"    else:"},{"line_number":56,"context_line":"        activity \u003d ret"},{"line_number":57,"context_line":"        ret \u003d None"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_f2533b69","line":54,"range":{"start_line":53,"start_character":4,"end_line":54,"end_character":18},"in_reply_to":"3ac371cc_86063fcc","updated":"2016-08-17 12:53:16.000000000","message":"Good idea, will fix","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"7e36fca1a3eb68c63883b0fa840460c91fdc92b5","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            return ret"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class Barrier(object):"},{"line_number":67,"context_line":"    def __init__(self, interval):"},{"line_number":68,"context_line":"        super(Barrier, self).__init__()"},{"line_number":69,"context_line":"        self._event \u003d Event()"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_66a503b4","line":66,"range":{"start_line":66,"start_character":6,"end_line":66,"end_character":13},"updated":"2016-08-16 16:00:57.000000000","message":"Barrier is a well known constract that has a different interface.\n\nMaybe name this TimedBarrier ?","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"c6cab9ec3b23672bc4d3ddcd37af4e0dc4ce8ecc","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            return ret"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class Barrier(object):"},{"line_number":67,"context_line":"    def __init__(self, interval):"},{"line_number":68,"context_line":"        super(Barrier, self).__init__()"},{"line_number":69,"context_line":"        self._event \u003d Event()"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_d84e216e","line":66,"range":{"start_line":66,"start_character":6,"end_line":66,"end_character":13},"in_reply_to":"3ac371cc_66a503b4","updated":"2016-08-17 12:53:16.000000000","message":"Will change :)","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"782b52555b6fbc36db8a0495b7d5a1a1d1fa38db","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            return ret"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class Barrier(object):"},{"line_number":67,"context_line":"    def __init__(self, interval):"},{"line_number":68,"context_line":"        super(Barrier, self).__init__()"},{"line_number":69,"context_line":"        self._event \u003d Event()"},{"line_number":70,"context_line":"        self._interval \u003d interval"},{"line_number":71,"context_line":"        self._looping_call \u003d FixedIntervalLoopingCall(self.send)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def start(self):"},{"line_number":74,"context_line":"        self._looping_call.start(self._interval)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    def stop(self):"},{"line_number":77,"context_line":"        self._looping_call.stop()"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def send(self):"},{"line_number":80,"context_line":"        old_event \u003d self._event"},{"line_number":81,"context_line":"        self._event \u003d Event()"},{"line_number":82,"context_line":"        old_event.send()"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def wait(self):"},{"line_number":85,"context_line":"        self._event.wait()"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def noop_activity(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_2d58d189","line":85,"range":{"start_line":66,"start_character":0,"end_line":85,"end_character":26},"updated":"2016-08-17 14:56:55.000000000","message":"Replacing the event object is problematic and kind of hackish.\nWhat about this?\n\nclass TimedBarrier(object):\n    def __init__(self, interval):\n        self._condition \u003d Condition()\n        self._interval \u003d interval\n        self._looping_call \u003d FixedIntervalLoopingCall(self._send)\n\n    def start(self):\n        self._looping_call.start(self._interval)\n\n    def stop(self):\n        self._looping_call.stop()\n\n    def wait(self):\n        self._condition.wait()\n\n    def _send(self):\n        self._condition.notify_all()","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"965dfdce68e2b12dfd354693ab87d83e3870272d","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            return ret"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class Barrier(object):"},{"line_number":67,"context_line":"    def __init__(self, interval):"},{"line_number":68,"context_line":"        super(Barrier, self).__init__()"},{"line_number":69,"context_line":"        self._event \u003d Event()"},{"line_number":70,"context_line":"        self._interval \u003d interval"},{"line_number":71,"context_line":"        self._looping_call \u003d FixedIntervalLoopingCall(self.send)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def start(self):"},{"line_number":74,"context_line":"        self._looping_call.start(self._interval)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    def stop(self):"},{"line_number":77,"context_line":"        self._looping_call.stop()"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def send(self):"},{"line_number":80,"context_line":"        old_event \u003d self._event"},{"line_number":81,"context_line":"        self._event \u003d Event()"},{"line_number":82,"context_line":"        old_event.send()"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def wait(self):"},{"line_number":85,"context_line":"        self._event.wait()"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def noop_activity(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_3dbd71d8","line":85,"range":{"start_line":66,"start_character":0,"end_line":85,"end_character":26},"in_reply_to":"3ac371cc_2d58d189","updated":"2016-08-18 07:28:16.000000000","message":"Do you refer to threading.Condition? I think it is not patched by eventlet.\n\nRegarding re-creating the Event(), it is explained as necessary in http://eventlet.net/doc/modules/event.html","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"782b52555b6fbc36db8a0495b7d5a1a1d1fa38db","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    pass"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def barrier_start():"},{"line_number":93,"context_line":"    barrier \u003d Barrier(CONF.async_task_interval)"},{"line_number":94,"context_line":"    barrier.start()"},{"line_number":95,"context_line":"    return barrier"}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_edefd984","line":92,"range":{"start_line":92,"start_character":4,"end_line":92,"end_character":17},"updated":"2016-08-17 14:56:55.000000000","message":"_timed_barrier_start()","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"782b52555b6fbc36db8a0495b7d5a1a1d1fa38db","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    return barrier"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"def barrier_stop(barrier):"},{"line_number":99,"context_line":"    barrier.stop()"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3ac371cc_8d53c538","line":98,"range":{"start_line":98,"start_character":4,"end_line":98,"end_character":16},"updated":"2016-08-17 14:56:55.000000000","message":"This should be prefixed with _ since it\u0027s just part of internal implementation details","commit_id":"bc8e951af42220d9a32af6d77e3e3d2983d4f4f5"}]}
