)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"1c974521fc878c1ab6a6b82a0a8d76f89dbacb69","unresolved":false,"context_lines":[{"line_number":9,"context_line":"In the long term, it could be a replacement for the PartitionedAlarmService. It"},{"line_number":10,"context_line":"uses the same basic idea: a master node keeps track of the alarms to be"},{"line_number":11,"context_line":"evaluated, but instead of distributing a slice of the alarms to each node, it"},{"line_number":12,"context_line":"just maintains a pool from which the other nodes can pick some work. This pool"},{"line_number":13,"context_line":"is managed by taskflow, for instance by using a multi-node Zookeeper"},{"line_number":14,"context_line":"configuration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"1ae5cdf2_941e56ba","line":12,"updated":"2014-06-16 18:37:08.000000000","message":"So the net effect is for alarms to be assigned to *different* evaluators on successive evaluations cycles?\n\nThis would be seem problematic in terms of maintaining a regular cadence of evaluation for an individual alarm, because the evaluation cycles of the individual evaluators would tend to be offset from each other (due to the random distribution of start times). \n\nSay we have evaluators {E1, E2, E3, E4} starting at times {T, T+15s, T+30s, T+45s}.\n\nSay the alarms set is currently {A1, A2, A3, A4}\n\nCould we have a scenario whereby alarm A1 is allocated E4 on the first cycle, E2 on the second cycle and then E1 on the third, resulting in 15s and 75s gaps between subsequent evaluations?\n\nIs there any way we could make the task-to-evaluator assignment more \"sticky\"?","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"8c8b5d128427450af80b695115123a95cfff7a91","unresolved":false,"context_lines":[{"line_number":9,"context_line":"In the long term, it could be a replacement for the PartitionedAlarmService. It"},{"line_number":10,"context_line":"uses the same basic idea: a master node keeps track of the alarms to be"},{"line_number":11,"context_line":"evaluated, but instead of distributing a slice of the alarms to each node, it"},{"line_number":12,"context_line":"just maintains a pool from which the other nodes can pick some work. This pool"},{"line_number":13,"context_line":"is managed by taskflow, for instance by using a multi-node Zookeeper"},{"line_number":14,"context_line":"configuration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"baada198_21a1f4a9","line":12,"in_reply_to":"1ae5cdf2_941e56ba","updated":"2014-06-30 15:28:13.000000000","message":"Alarms are not really \"assigned\" to an evaluator, they\u0027re \"picked\" by evaluators. So as long as an evaluator has not been started, an alarm cannot be \"assigned\" to it.\n\nThe daly between 2 evaluations of an alarm may change, depending on how fast it\u0027s picked up during the evaluation rounds.","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"657ff2caf27d8d0b13900493b93734f5b0a6c627","unresolved":false,"context_lines":[{"line_number":9,"context_line":"In the long term, it could be a replacement for the PartitionedAlarmService. It"},{"line_number":10,"context_line":"uses the same basic idea: a master node keeps track of the alarms to be"},{"line_number":11,"context_line":"evaluated, but instead of distributing a slice of the alarms to each node, it"},{"line_number":12,"context_line":"just maintains a pool from which the other nodes can pick some work. This pool"},{"line_number":13,"context_line":"is managed by taskflow, for instance by using a multi-node Zookeeper"},{"line_number":14,"context_line":"configuration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"baada198_3ad97257","line":12,"in_reply_to":"baada198_21a1f4a9","updated":"2014-07-13 05:40:15.000000000","message":"Cyril is right, think of the jobboard in this usage as highly-available queue,  that workers can extract work from, perform it and repeat so the workers are responsible for picking that work and doing it.\n\nhttp://docs.openstack.org/developer/taskflow/jobs.html hopefully helps understand what is going on here.","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"}],"ceilometer/alarm/partition/coordination.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2f3c7021609284e881749c2e051f4d86780862b2","unresolved":false,"context_lines":[{"line_number":326,"context_line":"    need for nodes to periodically report."},{"line_number":327,"context_line":"    \"\"\""},{"line_number":328,"context_line":"    @contextlib.contextmanager"},{"line_number":329,"context_line":"    def _fetch_job_board(self):"},{"line_number":330,"context_line":"        \"\"\"Yield a handle to the board that holds alarm evaluation jobs.\"\"\""},{"line_number":331,"context_line":"        job_board \u003d job_backends.fetch("},{"line_number":332,"context_line":"            \u0027alarm-board\u0027, {"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_eb96c193","line":329,"updated":"2014-05-02 10:53:51.000000000","message":"@staticmethod\n\nIt looks weird to me that you connect/disconnect from the job board each time. Why not connecting once and for all in __init__ ?","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"704f67d323a2fb8d870d2527ade3c8f5c5ac0aef","unresolved":false,"context_lines":[{"line_number":326,"context_line":"    need for nodes to periodically report."},{"line_number":327,"context_line":"    \"\"\""},{"line_number":328,"context_line":"    @contextlib.contextmanager"},{"line_number":329,"context_line":"    def _fetch_job_board(self):"},{"line_number":330,"context_line":"        \"\"\"Yield a handle to the board that holds alarm evaluation jobs.\"\"\""},{"line_number":331,"context_line":"        job_board \u003d job_backends.fetch("},{"line_number":332,"context_line":"            \u0027alarm-board\u0027, {"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_c8680cbd","line":329,"in_reply_to":"9ad9bd40_d2f99bc9","updated":"2014-05-02 22:29:01.000000000","message":"Should be fine to use a single jobboard, the zookeeper cluster will internally elect a new leader, the current running session may be lost, but a new session will then be created, so there might be a failure when this happens. We should verify this but there shouldn\u0027t be anything manual needed here to cause it to switch.","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"1149400bf979c0b87a548aac63e4b86ec3c677a3","unresolved":false,"context_lines":[{"line_number":326,"context_line":"    need for nodes to periodically report."},{"line_number":327,"context_line":"    \"\"\""},{"line_number":328,"context_line":"    @contextlib.contextmanager"},{"line_number":329,"context_line":"    def _fetch_job_board(self):"},{"line_number":330,"context_line":"        \"\"\"Yield a handle to the board that holds alarm evaluation jobs.\"\"\""},{"line_number":331,"context_line":"        job_board \u003d job_backends.fetch("},{"line_number":332,"context_line":"            \u0027alarm-board\u0027, {"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_d2f99bc9","line":329,"in_reply_to":"9ad9bd40_eb96c193","updated":"2014-05-02 21:31:07.000000000","message":"Yes, I\u0027d rather do that too. But let\u0027s just say that we have two zookeeper nodes, and one of them dies; does taskflow automatically use to the other one or do I have to manually \"switch\"? I wasn\u0027t sure of that, so I used a less efficient method to start with.\n\n@Joshua: is it ok to just connect once in __init__ and then use self._job_board everywhere in this class ?","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2f3c7021609284e881749c2e051f4d86780862b2","unresolved":false,"context_lines":[{"line_number":336,"context_line":"            }"},{"line_number":337,"context_line":"        )"},{"line_number":338,"context_line":"        job_board.connect()"},{"line_number":339,"context_line":"        time.sleep(0.3)  # XXX Required, but hacky"},{"line_number":340,"context_line":"        yield job_board"},{"line_number":341,"context_line":"        job_board.close()"},{"line_number":342,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_0b92059f","line":339,"updated":"2014-05-02 10:53:51.000000000","message":"Why required?","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c95e59a1d0d51e485e3e134102716516934e3a6c","unresolved":false,"context_lines":[{"line_number":336,"context_line":"            }"},{"line_number":337,"context_line":"        )"},{"line_number":338,"context_line":"        job_board.connect()"},{"line_number":339,"context_line":"        time.sleep(0.3)  # XXX Required, but hacky"},{"line_number":340,"context_line":"        yield job_board"},{"line_number":341,"context_line":"        job_board.close()"},{"line_number":342,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_bd3cedc0","line":339,"in_reply_to":"9ad9bd40_0b92059f","updated":"2014-05-02 18:27:36.000000000","message":"Hopefully not required. The reason I think this is here is that zookeeper watches will be activated asynchronously. This sleep is trying to let those watches to occur. To me though it seems like should not be needed (especially if just 1 jobboard exists, and not fetched all the time).","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"704f67d323a2fb8d870d2527ade3c8f5c5ac0aef","unresolved":false,"context_lines":[{"line_number":336,"context_line":"            }"},{"line_number":337,"context_line":"        )"},{"line_number":338,"context_line":"        job_board.connect()"},{"line_number":339,"context_line":"        time.sleep(0.3)  # XXX Required, but hacky"},{"line_number":340,"context_line":"        yield job_board"},{"line_number":341,"context_line":"        job_board.close()"},{"line_number":342,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_c8af2ce2","line":339,"in_reply_to":"9ad9bd40_72a52fb4","updated":"2014-05-02 22:29:01.000000000","message":"Ya, that\u0027s cause zookeeper will notify the board asynchronously. The newer taskflow release to be out will have an option to iterjobs(ensure_fresh\u003dTrue) which will force a fetch to occur, and not wait for zookeeper to asynchronously tell the jobboard about new jobs. This is one option, although has to be used correctly or a-lot of traffic will happen whenever an iterator is created and used.","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"1149400bf979c0b87a548aac63e4b86ec3c677a3","unresolved":false,"context_lines":[{"line_number":336,"context_line":"            }"},{"line_number":337,"context_line":"        )"},{"line_number":338,"context_line":"        job_board.connect()"},{"line_number":339,"context_line":"        time.sleep(0.3)  # XXX Required, but hacky"},{"line_number":340,"context_line":"        yield job_board"},{"line_number":341,"context_line":"        job_board.close()"},{"line_number":342,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_72a52fb4","line":339,"in_reply_to":"9ad9bd40_bd3cedc0","updated":"2014-05-02 21:31:07.000000000","message":"In the job board example written by Dan Krause and I (see https://review.openstack.org/#/c/91190/), if I remove the \"time.sleep(0.3)\" and try to add jobs to the board, and then list them all, I see none of them, so it seems a bit risky to me not to wait. WDYT ?","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"da611af702af788fca5266920a1cbea7fb259bda","unresolved":false,"context_lines":[{"line_number":350,"context_line":"    def _clear_evaluation_jobs(self):"},{"line_number":351,"context_line":"        \"\"\"Delete all alarm evaluation jobs.\"\"\""},{"line_number":352,"context_line":"        with self._fetch_job_board() as jb:"},{"line_number":353,"context_line":"            for job in jb.iterjobs():"},{"line_number":354,"context_line":"                jb.claim(job, \u0027\u0027)"},{"line_number":355,"context_line":"                jb.consume(job, \u0027\u0027)"},{"line_number":356,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_9daf29e3","line":353,"updated":"2014-05-02 18:30:03.000000000","message":"I presume this is where u want the clear() method to clear all jobs in the jobboard (this one will have to be done carefully; as what happens if other entities are at the same time creating jobs at the same location?)","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"704f67d323a2fb8d870d2527ade3c8f5c5ac0aef","unresolved":false,"context_lines":[{"line_number":350,"context_line":"    def _clear_evaluation_jobs(self):"},{"line_number":351,"context_line":"        \"\"\"Delete all alarm evaluation jobs.\"\"\""},{"line_number":352,"context_line":"        with self._fetch_job_board() as jb:"},{"line_number":353,"context_line":"            for job in jb.iterjobs():"},{"line_number":354,"context_line":"                jb.claim(job, \u0027\u0027)"},{"line_number":355,"context_line":"                jb.consume(job, \u0027\u0027)"},{"line_number":356,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_887d2471","line":353,"in_reply_to":"9ad9bd40_728c4f36","updated":"2014-05-02 22:29:01.000000000","message":"So can we assume that _create_evaluation_job will never be happening elsewhere, if we can ensure this then this is fine. If we can\u0027t then this won\u0027t work, as someone else can be running _create_evaluation_job at the same time as this loop is running.\n\nKnowing this we can decide what a good path may be.","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"1149400bf979c0b87a548aac63e4b86ec3c677a3","unresolved":false,"context_lines":[{"line_number":350,"context_line":"    def _clear_evaluation_jobs(self):"},{"line_number":351,"context_line":"        \"\"\"Delete all alarm evaluation jobs.\"\"\""},{"line_number":352,"context_line":"        with self._fetch_job_board() as jb:"},{"line_number":353,"context_line":"            for job in jb.iterjobs():"},{"line_number":354,"context_line":"                jb.claim(job, \u0027\u0027)"},{"line_number":355,"context_line":"                jb.consume(job, \u0027\u0027)"},{"line_number":356,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_728c4f36","line":353,"in_reply_to":"9ad9bd40_9daf29e3","updated":"2014-05-02 21:31:07.000000000","message":"That\u0027s where I would want the clear() method indeed.\n\nI believe doing \"claim(); consume()\" is safe. These operations are atomic, aren\u0027t they ? Or would I need to \"lock\" the whole board before cleaning the jobs ?","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"da611af702af788fca5266920a1cbea7fb259bda","unresolved":false,"context_lines":[{"line_number":376,"context_line":"            for job in jb.iterjobs(only_unclaimed\u003dTrue):"},{"line_number":377,"context_line":"                jb.claim(job, \"coordinator-%s\" % this)"},{"line_number":378,"context_line":"                if job is None:"},{"line_number":379,"context_line":"                    raise StopIteration"},{"line_number":380,"context_line":"                yield job"},{"line_number":381,"context_line":"                jb.consume(job)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_dd6291d7","line":379,"updated":"2014-05-02 18:30:03.000000000","message":"I think u can just do \u0027break\u0027 also","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"1149400bf979c0b87a548aac63e4b86ec3c677a3","unresolved":false,"context_lines":[{"line_number":376,"context_line":"            for job in jb.iterjobs(only_unclaimed\u003dTrue):"},{"line_number":377,"context_line":"                jb.claim(job, \"coordinator-%s\" % this)"},{"line_number":378,"context_line":"                if job is None:"},{"line_number":379,"context_line":"                    raise StopIteration"},{"line_number":380,"context_line":"                yield job"},{"line_number":381,"context_line":"                jb.consume(job)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ad9bd40_f2777f39","line":379,"in_reply_to":"9ad9bd40_dd6291d7","updated":"2014-05-02 21:31:07.000000000","message":"I\u0027ll have to check, but it\u0027s quite possible indeed.","commit_id":"029e823b428b9b6f4728b36760a0728fd1bcda8a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d6f13449b0581ad3215e2e3a4e86441e2a3845b5","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        time.sleep(0.3)"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    def stop(self):"},{"line_number":344,"context_line":"        self._job_board.close()"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def _create_evaluation_job(self, alarm):"},{"line_number":347,"context_line":"        \"\"\"Create an alarm evaluation job.\"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"7adec928_e03fb3d4","line":344,"updated":"2014-05-10 02:50:26.000000000","message":"Oops, I should probably do:\n\nsuper(TaskflowPartitionCoordinator, self).stop() here.","commit_id":"981c1a98717686a6465870ef287b865ce9dc0792"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d6f13449b0581ad3215e2e3a4e86441e2a3845b5","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        job_name \u003d \u0027eval-%s\u0027 % alarm.alarm_id"},{"line_number":351,"context_line":"        book \u003d logbook.LogBook(job_name)"},{"line_number":352,"context_line":"        jb.post(job_name, book, details\u003ddict(alarm\u003dalarm))"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"    def _clear_evaluation_jobs(self):"},{"line_number":355,"context_line":"        \"\"\"Delete all alarm evaluation jobs.\"\"\""},{"line_number":356,"context_line":"        # XXX(cyril): we need a clean \"clear\" method in taskflow."}],"source_content_type":"text/x-python","patch_set":2,"id":"7adec928_80198f8a","line":353,"updated":"2014-05-10 02:50:26.000000000","message":"Here, I have a weird error when running this service on a devstack. I get the following stacktrace:\n\nhttp://paste.openstack.org/show/79803\n\nNot sure why. @Joshua: any idea ? I don\u0027t see why there would be a circular reference in my alarm. I created it by running:\n\n\nceilometer alarm-threshold-create --name image_dummy_alarm --description \u0027dummy alarm\u0027 --meter-name image --threshold 70.0 --comparison-operator gt --statistic avg --period 10 --evaluation-periods 3\n\nIt\u0027s obviously a stupid alarm, but as long as I can see whether it\u0027s evaluated...","commit_id":"981c1a98717686a6465870ef287b865ce9dc0792"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d6f13449b0581ad3215e2e3a4e86441e2a3845b5","unresolved":false,"context_lines":[{"line_number":371,"context_line":"        # job board because it has not been evaluated yet. The easiest"},{"line_number":372,"context_line":"        # solution is to clear the whole board, and re-add all alarms, but"},{"line_number":373,"context_line":"        # there is reliable clear() method in taskflow yet. Can we find a"},{"line_number":374,"context_line":"        # better way of making sure not to add the same alarm twice?"},{"line_number":375,"context_line":"        self._clear_evaluation_jobs()"},{"line_number":376,"context_line":"        for alarm in api_client.alarms.list():"},{"line_number":377,"context_line":"            self._create_evaluation_job(alarm)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7adec928_c06e3701","line":374,"updated":"2014-05-10 02:50:26.000000000","message":"This is really a huge issue, I think.","commit_id":"981c1a98717686a6465870ef287b865ce9dc0792"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"e379feb78aef06c9c38426a7da2cbba1318c5af4","unresolved":false,"context_lines":[{"line_number":28,"context_line":"from ceilometer.openstack.common.gettextutils import _"},{"line_number":29,"context_line":"from ceilometer.openstack.common import log"},{"line_number":30,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"from ceilometer import storage"},{"line_number":33,"context_line":"from oslo.config import cfg"},{"line_number":34,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ae8d1ca_8b600437","line":31,"updated":"2014-05-27 16:34:03.000000000","message":"remove empty line","commit_id":"2d9ed5353383eb5110a240ed1f602cbf1efe06c8"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"e379feb78aef06c9c38426a7da2cbba1318c5af4","unresolved":false,"context_lines":[{"line_number":30,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"from ceilometer import storage"},{"line_number":33,"context_line":"from oslo.config import cfg"},{"line_number":34,"context_line":"CONF \u003d cfg.CONF"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3ae8d1ca_2b6a901a","line":33,"updated":"2014-05-27 16:34:03.000000000","message":"group this with taskflow lib","commit_id":"2d9ed5353383eb5110a240ed1f602cbf1efe06c8"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"890dfdc34ac4af5041f88d332437ddb7416bee52","unresolved":false,"context_lines":[{"line_number":30,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"from ceilometer import storage"},{"line_number":33,"context_line":"from oslo.config import cfg"},{"line_number":34,"context_line":"CONF \u003d cfg.CONF"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3ae8d1ca_9721dea1","line":33,"in_reply_to":"3ae8d1ca_2b6a901a","updated":"2014-05-28 14:08:32.000000000","message":"yep, to keep three groups of modules:\n\n- python built-in (like math, ..)\n- 3rd party ones - the ones you pick in the requirements\n- this project modules","commit_id":"2d9ed5353383eb5110a240ed1f602cbf1efe06c8"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"890dfdc34ac4af5041f88d332437ddb7416bee52","unresolved":false,"context_lines":[{"line_number":337,"context_line":"            \u0027alarm-board\u0027, {"},{"line_number":338,"context_line":"                \u0027board\u0027: \u0027zookeeper\u0027,"},{"line_number":339,"context_line":"                # XXX Make this configurable with multiple hosts"},{"line_number":340,"context_line":"                \u0027hosts\u0027: [\u0027127.0.0.1:2181\u0027]"},{"line_number":341,"context_line":"            }"},{"line_number":342,"context_line":"        )"},{"line_number":343,"context_line":"        self._job_board.connect()"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ae8d1ca_d768c6bc","line":340,"updated":"2014-05-28 14:08:32.000000000","message":"just a nitpick: when you\u0027re writing lists/dicts on several lines keep commas even if it\u0027s only one elem in the object. That keeps reviews clearer when it\u0027ll be next change in this place - to change one line, not two:\n\n\n{\n\u0027board\u0027: \u0027zookeeper\u0027,\n\n\u0027hosts\u0027: [...],\n\n}","commit_id":"2d9ed5353383eb5110a240ed1f602cbf1efe06c8"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"890dfdc34ac4af5041f88d332437ddb7416bee52","unresolved":false,"context_lines":[{"line_number":379,"context_line":"            jb.claim(job, \"coordinator-%s\" % self.this)"},{"line_number":380,"context_line":"            if job is None:"},{"line_number":381,"context_line":"                break"},{"line_number":382,"context_line":"            LOG.debug(\u0027%s picking up alarm %s\u0027 %"},{"line_number":383,"context_line":"                      (self.this, job.details[\u0027alarm\u0027]))"},{"line_number":384,"context_line":"            alarm \u003d list(self.conn.get_alarms(alarm_id\u003djob.details[\u0027alarm\u0027]))"},{"line_number":385,"context_line":"            yield alarm[0]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ae8d1ca_97cb9ea4","line":382,"updated":"2014-05-28 14:08:32.000000000","message":"if there are multiple strings inserted while string formatting, please use the following format:\n\n\"%(s1)s test %(s2)s\" % {\u0027s1\u0027: obj1, \u0027s2\u0027: obj2}","commit_id":"2d9ed5353383eb5110a240ed1f602cbf1efe06c8"},{"author":{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},"change_message_id":"02883b4143c14b87c576384f58479e3680390d3e","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        LOG.debug(\u0027%s fetching the job board\u0027 % self.this)"},{"line_number":333,"context_line":"        self._job_board \u003d job_backends.fetch("},{"line_number":334,"context_line":"            \u0027alarm-board\u0027, {"},{"line_number":335,"context_line":"                \u0027board\u0027: \u0027zookeeper\u0027,"},{"line_number":336,"context_line":"                \u0027hosts\u0027: CONF.alarm.taskflow_hosts,"},{"line_number":337,"context_line":"            }"},{"line_number":338,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_bce878b5","line":335,"updated":"2014-06-02 00:44:10.000000000","message":"Why are we not getting this from a config option? is zookeeper really the only option?","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7d2fb21232aeff5013905050713afa47f2123787","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        LOG.debug(\u0027%s fetching the job board\u0027 % self.this)"},{"line_number":333,"context_line":"        self._job_board \u003d job_backends.fetch("},{"line_number":334,"context_line":"            \u0027alarm-board\u0027, {"},{"line_number":335,"context_line":"                \u0027board\u0027: \u0027zookeeper\u0027,"},{"line_number":336,"context_line":"                \u0027hosts\u0027: CONF.alarm.taskflow_hosts,"},{"line_number":337,"context_line":"            }"},{"line_number":338,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_4dd060f6","line":335,"in_reply_to":"1ae5cdf2_745c3cee","updated":"2014-06-03 17:27:59.000000000","message":"There have been ideas about writing one that uses raft, etcd, or other capable system (marconi currently isn\u0027t deemed capable enough for this). Contributions are welcome to include something new assuming that the underlying system \u0026 implementation is capable and works (I don\u0027t know of many systems that support the correct semantics to make this work correctly in a production environment).","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"4b85ea5d7c1e392a93f2fbff97fdba88b83b3e1c","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        LOG.debug(\u0027%s fetching the job board\u0027 % self.this)"},{"line_number":333,"context_line":"        self._job_board \u003d job_backends.fetch("},{"line_number":334,"context_line":"            \u0027alarm-board\u0027, {"},{"line_number":335,"context_line":"                \u0027board\u0027: \u0027zookeeper\u0027,"},{"line_number":336,"context_line":"                \u0027hosts\u0027: CONF.alarm.taskflow_hosts,"},{"line_number":337,"context_line":"            }"},{"line_number":338,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_745c3cee","line":335,"in_reply_to":"1ae5cdf2_bce878b5","updated":"2014-06-02 11:22:43.000000000","message":"As for the zookeeper - it\u0027s the only existing coordinator, as far as I know (not speaking about something self-written). So in this case it\u0027s really the only option. Although it requires lots of deploying efforts itself.. Probably, there is some other coordinator option, but I guess it\u0027ll be something self-developed in this case.","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e0b7d2e7e2a64cebf092dd3db45fa7864f52b79d","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        LOG.debug(\u0027Adding %s to the alarms to evaluate\u0027 % alarm.alarm_id)"},{"line_number":350,"context_line":"        jb \u003d self._job_board"},{"line_number":351,"context_line":"        job_name \u003d \u0027eval-%s\u0027 % alarm.alarm_id"},{"line_number":352,"context_line":"        book \u003d logbook.LogBook(job_name)"},{"line_number":353,"context_line":"        jb.post(job_name, book, details\u003ddict(alarm\u003dalarm.alarm_id))"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"    def _master_role(self, assuming, api_client):"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_28aee785","line":352,"updated":"2014-06-01 21:46:21.000000000","message":"So this is fine, but may not be useful if u aren\u0027t persisting the book anywhere. Maybe there should be a way to leave out a book when posting (or default it to None) so that this can just be skipped (and u can post details as needed like u are using already).","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a27548eb5af6f4efc4643a485c772316418b2c8f","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        \"\"\"Create an alarm evaluation job.\"\"\""},{"line_number":344,"context_line":"        LOG.debug(\u0027Adding %s to the alarms to evaluate\u0027 % alarm.alarm_id)"},{"line_number":345,"context_line":"        jb \u003d self._job_board"},{"line_number":346,"context_line":"        job_name \u003d \u0027eval-%s\u0027 % alarm.alarm_id"},{"line_number":347,"context_line":"        book \u003d logbook.LogBook(job_name)"},{"line_number":348,"context_line":"        jb.post(job_name, book, details\u003ddict(alarm\u003dalarm.alarm_id))"},{"line_number":349,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_3a6412b8","line":346,"updated":"2014-07-13 05:27:54.000000000","message":"Can u open a bug to allow jobs to be posted with no logbook, seems like u are not using it anyway (you are instead using the details dictionary as the data transfer mechanism), so we might as well allow it to be none/not provided for those use-cases where just knowing the details dictionary is good enough. Thx!","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ae93605285cbd05feff4db5ca4d811bed780cd06","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        \"\"\"Create an alarm evaluation job.\"\"\""},{"line_number":344,"context_line":"        LOG.debug(\u0027Adding %s to the alarms to evaluate\u0027 % alarm.alarm_id)"},{"line_number":345,"context_line":"        jb \u003d self._job_board"},{"line_number":346,"context_line":"        job_name \u003d \u0027eval-%s\u0027 % alarm.alarm_id"},{"line_number":347,"context_line":"        book \u003d logbook.LogBook(job_name)"},{"line_number":348,"context_line":"        jb.post(job_name, book, details\u003ddict(alarm\u003dalarm.alarm_id))"},{"line_number":349,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_3a3252a7","line":346,"in_reply_to":"baada198_3a6412b8","updated":"2014-07-13 05:31:54.000000000","message":"*Btw, bug/bp was for taskflow, not for ceilometer ;)","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a27548eb5af6f4efc4643a485c772316418b2c8f","unresolved":false,"context_lines":[{"line_number":345,"context_line":"        jb \u003d self._job_board"},{"line_number":346,"context_line":"        job_name \u003d \u0027eval-%s\u0027 % alarm.alarm_id"},{"line_number":347,"context_line":"        book \u003d logbook.LogBook(job_name)"},{"line_number":348,"context_line":"        jb.post(job_name, book, details\u003ddict(alarm\u003dalarm.alarm_id))"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def _master_role(self, assuming, api_client):"},{"line_number":351,"context_line":"        \"\"\"Carry out the master role, populating the job board if necessary."}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_9a727e7a","line":348,"updated":"2014-07-13 05:27:54.000000000","message":"Another thing, how do u want to handle posting errors. If the backend connection fails then whats the expected result (this will raise an exception with details about what happened, probably u just need to catch it/handle it/log it and rethrow it?)","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"1c974521fc878c1ab6a6b82a0a8d76f89dbacb69","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        # very clean, but it does not really matter if an alarm is evaluated"},{"line_number":360,"context_line":"        # twice."},{"line_number":361,"context_line":"        for alarm in api_client.alarms.list():"},{"line_number":362,"context_line":"            self._create_evaluation_job(alarm)"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"        return self.this \u003c self.oldest"},{"line_number":365,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1ae5cdf2_f4779a9d","line":362,"updated":"2014-06-16 18:37:08.000000000","message":"The timing doesn\u0027t seem right here.\n\nThe check_mastership method is called by default at twice the frequency that alarms are evaluated at.\n\nSo unless I\u0027ve misunderstood, it seems we\u0027re creating twice as many evaluation jobs as there are are actual evaluations to be done?\n\nOr is job creation intended to be idempotent? Even so, is it suboptimal to call it twice as often as is necessary?","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"8c8b5d128427450af80b695115123a95cfff7a91","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        # very clean, but it does not really matter if an alarm is evaluated"},{"line_number":360,"context_line":"        # twice."},{"line_number":361,"context_line":"        for alarm in api_client.alarms.list():"},{"line_number":362,"context_line":"            self._create_evaluation_job(alarm)"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"        return self.this \u003c self.oldest"},{"line_number":365,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_fe2b1992","line":362,"in_reply_to":"1ae5cdf2_f4779a9d","updated":"2014-06-30 15:28:13.000000000","message":"Hum, right, looks like an issue. Not sure how to solve it, though. Mehdi, Joshua, any idea on this ?","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a27548eb5af6f4efc4643a485c772316418b2c8f","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        # very clean, but it does not really matter if an alarm is evaluated"},{"line_number":360,"context_line":"        # twice."},{"line_number":361,"context_line":"        for alarm in api_client.alarms.list():"},{"line_number":362,"context_line":"            self._create_evaluation_job(alarm)"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"        return self.this \u003c self.oldest"},{"line_number":365,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_da5156da","line":362,"in_reply_to":"baada198_fe2b1992","updated":"2014-07-13 05:27:54.000000000","message":"Unsure, seems like a internal detail that I\u0027m not aware of :-/","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"1c974521fc878c1ab6a6b82a0a8d76f89dbacb69","unresolved":false,"context_lines":[{"line_number":366,"context_line":"    def assigned_alarms(self, api_client):"},{"line_number":367,"context_line":"        \"\"\"Yield an alarm that has to be evaluated.\"\"\""},{"line_number":368,"context_line":"        jb \u003d self._job_board"},{"line_number":369,"context_line":"        for job in jb.iterjobs(only_unclaimed\u003dTrue, ensure_fresh\u003dTrue):"},{"line_number":370,"context_line":"            jb.claim(job, \"coordinator-%s\" % self.this)"},{"line_number":371,"context_line":"            if job is None:"},{"line_number":372,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ae5cdf2_74462a23","line":369,"updated":"2014-06-16 18:37:08.000000000","message":"The only_unclaimed\u003dTrue condition only holds at the outset of the iteration, right?\n\nIn which case, two evaluators looping at or around the same time could end up attempting to claim the same jobs, or?","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"8c8b5d128427450af80b695115123a95cfff7a91","unresolved":false,"context_lines":[{"line_number":366,"context_line":"    def assigned_alarms(self, api_client):"},{"line_number":367,"context_line":"        \"\"\"Yield an alarm that has to be evaluated.\"\"\""},{"line_number":368,"context_line":"        jb \u003d self._job_board"},{"line_number":369,"context_line":"        for job in jb.iterjobs(only_unclaimed\u003dTrue, ensure_fresh\u003dTrue):"},{"line_number":370,"context_line":"            jb.claim(job, \"coordinator-%s\" % self.this)"},{"line_number":371,"context_line":"            if job is None:"},{"line_number":372,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_5e9fa503","line":369,"in_reply_to":"1ae5cdf2_74462a23","updated":"2014-06-30 15:28:13.000000000","message":"I hope not. @Joshua: could you enlighten us here ?","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a27548eb5af6f4efc4643a485c772316418b2c8f","unresolved":false,"context_lines":[{"line_number":366,"context_line":"    def assigned_alarms(self, api_client):"},{"line_number":367,"context_line":"        \"\"\"Yield an alarm that has to be evaluated.\"\"\""},{"line_number":368,"context_line":"        jb \u003d self._job_board"},{"line_number":369,"context_line":"        for job in jb.iterjobs(only_unclaimed\u003dTrue, ensure_fresh\u003dTrue):"},{"line_number":370,"context_line":"            jb.claim(job, \"coordinator-%s\" % self.this)"},{"line_number":371,"context_line":"            if job is None:"},{"line_number":372,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_7a43ea12","line":369,"in_reply_to":"baada198_5e9fa503","updated":"2014-07-13 05:27:54.000000000","message":"So its for the full iteration, not just at outset.\n\nThe code is @ https://github.com/openstack/taskflow/blob/master/taskflow/jobs/backends/impl_zookeeper.py#L246\n\nThat said you need to handle the jb.claim raising an error that someone else has already claimed it, since even with checks that happen during iteration it can not be 100% guarnateed that someone else will not claim it during that period, there is no distributed lock (that would kill performance)  held on the jobboard while iterating so even if the iterator tries to ensure that the job is unclaimed the case needs to be handled where it really wasn\u0027t on claim() call.","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a27548eb5af6f4efc4643a485c772316418b2c8f","unresolved":false,"context_lines":[{"line_number":379,"context_line":"                    \u0027value\u0027: job.details[\u0027alarm\u0027],"},{"line_number":380,"context_line":"                }])"},{"line_number":381,"context_line":"                yield alarm[0]"},{"line_number":382,"context_line":"            except Exception:"},{"line_number":383,"context_line":"                LOG.exception(_(\u0027assignment retrieval failed\u0027))"},{"line_number":384,"context_line":"                jb.abandon(job, \"coordinator-%s\" % self.this)"},{"line_number":385,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_da68768a","line":382,"updated":"2014-07-13 05:27:54.000000000","message":"So this is an interesting one, when you abandon that means some other coordinator can pick it up and try it again, if that coordinator also fails this will cause it to abandon it (and so-on...). This creates a big loop that may never end. So just something to be aware of; \n\nhttps://blueprints.launchpad.net/taskflow/+spec/jobboard-garbage-bin is part of this (with more details there).","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"}],"ceilometer/cli.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e0b7d2e7e2a64cebf092dd3db45fa7864f52b79d","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    cfg.StrOpt(\u0027evaluation_service\u0027,"},{"line_number":53,"context_line":"               default\u003d\u0027ceilometer.alarm.service.SingletonAlarmService\u0027,"},{"line_number":54,"context_line":"               help\u003d\u0027Class to launch as alarm evaluation service.\u0027),"},{"line_number":55,"context_line":"    cfg.ListOpt(\u0027taskflow_hosts\u0027,"},{"line_number":56,"context_line":"                default\u003d[],"},{"line_number":57,"context_line":"                help\u003d\u0027Taskflow hosts for the TaskflowPartitionCoordinator.\u0027),"},{"line_number":58,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_a8b117e3","line":55,"updated":"2014-06-01 21:46:21.000000000","message":"This is really zookeeper hosts right?","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"2dbac48d29ea36a285a2757f652e64a2e0173374","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    cfg.StrOpt(\u0027evaluation_service\u0027,"},{"line_number":53,"context_line":"               default\u003d\u0027ceilometer.alarm.service.SingletonAlarmService\u0027,"},{"line_number":54,"context_line":"               help\u003d\u0027Class to launch as alarm evaluation service.\u0027),"},{"line_number":55,"context_line":"    cfg.ListOpt(\u0027taskflow_hosts\u0027,"},{"line_number":56,"context_line":"                default\u003d[],"},{"line_number":57,"context_line":"                help\u003d\u0027Taskflow hosts for the TaskflowPartitionCoordinator.\u0027),"},{"line_number":58,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":4,"id":"1ae5cdf2_bc7dd870","line":55,"in_reply_to":"1ae5cdf2_a8b117e3","updated":"2014-06-01 23:29:14.000000000","message":"Yes, but should Ceilometer users know about it ? They\u0027re really using Taskflow, they do not really care about the backend. Do you think this option would be much different if another backend was used ?","commit_id":"a5a5aeb0b2019dac7b2ff82782af37ea89fedae1"}],"ceilometer/tests/alarm/partition/test_coordination.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"17c7778ff60d42525b0dcdc44f0639a68d850135","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        # as Zookeeper, and probably fail. To prevent this from happening, we"},{"line_number":192,"context_line":"        # mock taskflow.jobs.backends.fetch so that it\u0027s harmless, and later"},{"line_number":193,"context_line":"        # initialize taskflow using zake, which allows us to \u0027mock\u0027 the"},{"line_number":194,"context_line":"        # Zookeeper backend."},{"line_number":195,"context_line":"        with mock.patch(\u0027taskflow.jobs.backends.fetch\u0027,"},{"line_number":196,"context_line":"                        return_value\u003dmock.Mock()):"},{"line_number":197,"context_line":"            self.partition_coordinator \u003d \\"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_daff96a9","line":194,"updated":"2014-07-13 05:30:39.000000000","message":"Cool, good thinking.","commit_id":"b280f12a30991c3ba8500a4659369545cbf47653"}]}
