)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"30508c55a2ab8ce00c271bb9e1bfb89a0d0a9e22","unresolved":false,"context_lines":[{"line_number":23,"context_line":"The `PartitionCoordinator` uses `tooz` to figure out which agents are"},{"line_number":24,"context_line":"in the same group and figures out which resources belong to the"},{"line_number":25,"context_line":"current agent."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: I7adef87b03129f4f8b38109bf547c7403cc6adad"},{"line_number":28,"context_line":"Implements: blueprint central-agent-partitioning"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"7ac7a964_0b3a3ccd","line":26,"updated":"2014-08-14 10:11:57.000000000","message":"Can you add the DocImpact tag also, so that we\u0027ve get an auto-generated docco bug? We could add a description of the mechanism and the user-visible config etc. in the new Admin Guide telemetry section that ildikov is currently writing,","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"}],"ceilometer/agent.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"139e333d4f4d46880d3f1776366ac08424955fcf","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_0cc23902","line":113,"updated":"2014-08-13 15:15:59.000000000","message":"Remind me as to why we need a group per discovery extension?\n\nAlso, since this is the agent superclass, will we be needlessly attempting to join a tooz group from an unpartitioned agent such as compute?\n\nShould this logic be either pushed down into the central agent subclass, or the discovery extension checked to see if it\u0027s partition-aware?\n\n(Explicitly calling out that partition awareness on a per-discovery-extension basis was one of the reasons I kinda liked the initial decorator-based approach)","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"d62be44a974fcd6faf1977d5330b8db4a3de3fa4","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_9e83efcb","line":113,"in_reply_to":"7ac7a964_425edfea","updated":"2014-08-14 09:43:39.000000000","message":"@Fabio\n\nOf your two options presented, #2 seems most workable to me, as encoding an initial list of the foreseeable central agents in each agent\u0027s config seems to be quite static and to run counter to the goal of this being a dynamic/fluid mechanism.\n\nHowever, that said, we should also consider whether the outcome of eagerly under-partitioning the target resources (i.e. splitting the global set into too few subsets initially, as not all agents have yet started up) is actually something we can tolerate.\n\nSeems that the result would be simply more than the expected number of samples for certain resources, during that period of churn as agents are being restarted.\n\nThe pathological case would I guess be a widely scaled out array of central agents, all being restarted in unison, e.g. as a result of an upgrade.\n\nIn this case, I wonder would it make sense for each partition coordinator to check the join times of the preceding members of the group, and to adaptively size their wait period on that basis?\n\nNejc, are join-timestamps actually surfaced in the group-membership primitives provided by tooz?","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"77c33bacf9721c04d0b0a7393b052923d37f77c7","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_425edfea","line":113,"in_reply_to":"7ac7a964_9d87840f","updated":"2014-08-14 07:12:41.000000000","message":"I think we should concentrate on #2, since it\u0027d be more dynamic if we didn\u0027t have to list our agents up front.\n\nYour suggestion seems great at first, but imagine this siguation:\n \nJ - agent joins group\nP - agent polls\nW - agent waits for another full interval from this point on\n\nagent |               time\n-----------------------------------------\u003e\n    1 | J -- W - W --- P --- P ...\n    2 |      J - W --- P --- P ...\n    3 |          J --- P --- P ...\n\nwhere a stampeding herd effect arises, all members of the group starting to poll at the same time. It would also mess with the cadency of the polling cycle, where an agent joining would delay the polling cycle which would thus happen at irregular intervals.\n\nWhereas if we just wait for one interval *independently*, we avoid that. The cost is that when an agent joins/leaves, the resources partitioning is consistent when all the group members start their *next* polling cycle from the point in time when an agent joined/left (not immediately).\n\nagent |               time\n-----------------------------------------\u003e\n    1 | J --- P --- P --- P ...\n    2 |    J --- P --- P --- P ...\n    3 |        J --- P --- P --- P ...\n\nThis is actually already implemented in this patch. When I mentioned synchronization above, I mean *within* the agent, not *between* agents. When starting up, we need to join potentially a lot of groups and we should be sure we have already joined them first. After thinking about it some more, this is already ensured, since on every partitioning, the PartitionCoordinator ensures that we are members of that group first.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f2197216326afed72ca36a74695ec6b758ca8893","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_cbb6848a","line":113,"in_reply_to":"7ac7a964_9e83efcb","updated":"2014-08-14 10:26:21.000000000","message":"Not explicitly, but each member can pass a data dict to tooz when it joins a group and we could store a timestamp in that.\n\nBut do we want to add this complexity? If each agent needs approximately the same time to restart, they will all come back online within one polling interval. If the polling interval is so short that some agents come online before others, the ones online simply partition the workload amongst themselves until others come online.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"8689b9b837eee7190a6996230b5913cc5ef50092","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_2e3e26b9","line":113,"in_reply_to":"7ac7a964_cbb6848a","updated":"2014-08-14 10:30:58.000000000","message":"Fair point, the churn of over-sampling in just a small number of initial periods doesn\u0027t seem like a deal-breaker.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"97563449559ba878c1dda7ab07b16037a83ed57a","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_40e230d5","line":113,"in_reply_to":"baada198_0cc23902","updated":"2014-08-13 16:22:41.000000000","message":"We don\u0027t. This just ensures we join all the necessary groups when the service is started (it should actually be in the start() method). The call to partition_coordinator.join_group() doesn\u0027t do anything if we are already in that group (it has a local list of joined groups).\n\nWe need to join the groups some time *before* we do the first round of polling, so we know our peers by the time we need to partition resources. Which reminds me, we should have some sort of synchronization going on - we shouldn\u0027t poll before all the groups are joined, relying on it taking less time than one polling interval is not very robust.\n\nWe could say that if a Discovery\u0027s group_id property is None, don\u0027t do partitioning at all, or indeed we could push it down to the central agent subclass. But remind me why would we explicitly prevent compute agent from being partitioned? If you want, run one per compute node, if you want more, run more, I don\u0027t really see the harm.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"083c916435235f0c1bfe9bf3ce1bfc4638a7ab7f","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_adb86413","line":113,"in_reply_to":"baada198_40e230d5","updated":"2014-08-13 17:11:21.000000000","message":"\u003e We don\u0027t ...\n\nA-ha, I see. So the fact that the group_id property defaults to \u0027global\u0027 for all current discovery extensions, results in this for loop usually only joining a *single* group, with the MemberAlreadyExist exception swallowed otherwise.\n\nWould it be a bit less oblique though to do something like:\n\n  groups \u003d set([d.obj.group_id for d in in self.discovery_manager])\n  for group in groups:\n      self.partition_coordinator.join_group(group)\n\nand avoid the needless additional call-outs to tooz?\n\n\u003e But remind me why would we explicitly prevent compute agent from being partitioned?\n\nGood point, I guess we don\u0027t really need to do so (despite the focus of this BP being the central agent scale-out).\n\nIf the compute agent uses its own config, then by default the coordination_backend_url could be unset, causing the join_group to be an no-op, which is fine.\n\nHowever the following might be worth thinking about:\n* where the compute and central agent share the same ceilometer.conf, then the (usually unpartitioned) compute agent would end up needlessly calling out to tooz to manage a trivial partitioning (i.e. the individual unpartitioned compute agent should always get *all* the instances running on the local node)\n* wouldn\u0027t the group_id property on the InstanceDiscovery[1] need to be over-ridden to be something unique such as cfg.CONF.host so that compute agents running on separate nodes don\u0027t cross-partition as a result of being in the same \u0027global\u0027 group? \n\n[1] https://github.com/openstack/ceilometer/blob/master/ceilometer/compute/discovery.py#L24","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":7052,"name":"Fabio Giannetti","email":"fgiannet@cisco.com","username":"fabgia"},"change_message_id":"b6c91b8ce1840a3a59670e780eb36076fc56eb34","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_9d87840f","line":113,"in_reply_to":"baada198_40e230d5","updated":"2014-08-14 01:40:19.000000000","message":"\u003e synchronization going on - we shouldn\u0027t poll before all the groups are joined, relying on it taking less time than one polling interval is not very robust.\n\nI agree. You need to have a concept of readiness, something that tells you the group has been joined by all the \"foreseeable\" central agents.\n\nI can see two cases:\n\n1) Central Agents share the same config: each can pass the list of hosts and instances for the central agents that are going to be started, like when you have several queue_host/queue_port in Oslo when they join and then Tooz can understand when all of them have joined or timeout.\n\n2) Central Agents have their own config: there should be a configurable interval parameter for the heartbeat the Tooz config. When a Central Agent joins, Tooz will wait a full heartbeat. If during that a new Central Agent joins then the heartbeat interval is considered from the time the new Central Agent has joined. The bottom line is that a heartbeat has been received at the same time from all the Central Agents in the group and no new one have joined, then the group is good to go.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f6149994a14ec249c8b587e62753de8ca31b8222","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.context \u003d context.RequestContext(\u0027admin\u0027, \u0027admin\u0027, is_admin\u003dTrue)"},{"line_number":111,"context_line":"        self.partition_coordinator \u003d partitioning.PartitionCoordinator()"},{"line_number":112,"context_line":"        for discoverer in self.discovery_manager:"},{"line_number":113,"context_line":"            self.partition_coordinator.join_group(discoverer.obj.group_id)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    @staticmethod"},{"line_number":116,"context_line":"    def _extensions(category, agent_ns\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_2d771304","line":113,"in_reply_to":"baada198_adb86413","updated":"2014-08-14 10:15:59.000000000","message":"Done","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"083deab0ffc870f856ef502ab4d03ff43589be4f","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                              interval,  # allow time for coordination"},{"line_number":163,"context_line":"                              task\u003dtask)"},{"line_number":164,"context_line":"            min_interval \u003d min(min_interval, interval)"},{"line_number":165,"context_line":"        self.tg.add_timer(min_interval / 4,"},{"line_number":166,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_1f3c362f","line":165,"updated":"2014-08-14 11:54:06.000000000","message":"Our of curiosity (sorry if I missed it earlier) why 4 here as opposed to anything else?","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"e4b0302fdf4d7bc3945924492b002ffdb58b3462","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                              interval,  # allow time for coordination"},{"line_number":163,"context_line":"                              task\u003dtask)"},{"line_number":164,"context_line":"            min_interval \u003d min(min_interval, interval)"},{"line_number":165,"context_line":"        self.tg.add_timer(min_interval / 4,"},{"line_number":166,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"1abeadc6_ae3b1dea","line":165,"in_reply_to":"7ac7a964_0b41465a","updated":"2014-08-18 14:29:28.000000000","message":"Done","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"557e55f4d0d281d6aedc52270d64243e2fe87d20","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                              interval,  # allow time for coordination"},{"line_number":163,"context_line":"                              task\u003dtask)"},{"line_number":164,"context_line":"            min_interval \u003d min(min_interval, interval)"},{"line_number":165,"context_line":"        self.tg.add_timer(min_interval / 4,"},{"line_number":166,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_ba09902e","line":165,"in_reply_to":"7ac7a964_1f3c362f","updated":"2014-08-14 11:59:19.000000000","message":"It\u0027s because the partitioned alarm evaluator does the same thing currently.\n\nhttps://github.com/openstack/ceilometer/blob/6a19c940fb463b9bc5a9c0e9b1572071da75af69/ceilometer/alarm/service.py#L152\n\nShould this be user configurable? What if a user shortens the polling interval, but forgets to change the heartbeat interval?","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":7052,"name":"Fabio Giannetti","email":"fgiannet@cisco.com","username":"fabgia"},"change_message_id":"d9b6e77495fa13ec4a4fd396f7776ee8ecdf71e2","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                              interval,  # allow time for coordination"},{"line_number":163,"context_line":"                              task\u003dtask)"},{"line_number":164,"context_line":"            min_interval \u003d min(min_interval, interval)"},{"line_number":165,"context_line":"        self.tg.add_timer(min_interval / 4,"},{"line_number":166,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_0b41465a","line":165,"in_reply_to":"7ac7a964_ba09902e","updated":"2014-08-14 18:58:01.000000000","message":"The heartbeat should be configurable and sensibly shorter than the polling interval. You probably want to get a heartbeat per second or so. This also has the advantage that all the heartbeat are going at the same time and are not directly dependent on the polling.","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        for interval, task in six.iteritems(self.setup_polling_tasks()):"},{"line_number":167,"context_line":"            self.tg.add_timer(interval,"},{"line_number":168,"context_line":"                              self.interval_task,"},{"line_number":169,"context_line":"                              initial_delay\u003dinterval if delay_start else 0,"},{"line_number":170,"context_line":"                              task\u003dtask)"},{"line_number":171,"context_line":"        self.tg.add_timer(cfg.CONF.coordination.heartbeat,"},{"line_number":172,"context_line":"                          self.partition_coordinator.heartbeat)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_f3fcde40","line":169,"updated":"2014-08-19 14:20:12.000000000","message":"maybe put None instead of 0 since that\u0027s the standard default.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        for interval, task in six.iteritems(self.setup_polling_tasks()):"},{"line_number":167,"context_line":"            self.tg.add_timer(interval,"},{"line_number":168,"context_line":"                              self.interval_task,"},{"line_number":169,"context_line":"                              initial_delay\u003dinterval if delay_start else 0,"},{"line_number":170,"context_line":"                              task\u003dtask)"},{"line_number":171,"context_line":"        self.tg.add_timer(cfg.CONF.coordination.heartbeat,"},{"line_number":172,"context_line":"                          self.partition_coordinator.heartbeat)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_ba5137da","line":169,"in_reply_to":"1abeadc6_f3fcde40","updated":"2014-08-20 06:00:43.000000000","message":"Done","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"df01c0fdb81c422865c45288cff4459563044576","unresolved":false,"context_lines":[{"line_number":158,"context_line":"    def start(self):"},{"line_number":159,"context_line":"        self.pipeline_manager \u003d pipeline.setup_pipeline()"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        self.join_partitioning_groups()"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        # allow time for coordination if necessary"},{"line_number":164,"context_line":"        delay_start \u003d self.partition_coordinator.is_active()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1abeadc6_e9a82f8f","line":161,"updated":"2014-08-20 21:34:06.000000000","message":"is there suppose to be a partition_coordinator start call before this? it seems like without it, join_partitioning_groups() and is_active() do nothing","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"b8d41f7b19bc64d8ca6595cfb0b2794247910244","unresolved":false,"context_lines":[{"line_number":158,"context_line":"    def start(self):"},{"line_number":159,"context_line":"        self.pipeline_manager \u003d pipeline.setup_pipeline()"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        self.join_partitioning_groups()"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        # allow time for coordination if necessary"},{"line_number":164,"context_line":"        delay_start \u003d self.partition_coordinator.is_active()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1abeadc6_63227353","line":161,"in_reply_to":"1abeadc6_e9a82f8f","updated":"2014-08-21 05:33:31.000000000","message":"Whew, thanks for catching this! The latest patch moved the actual startup out of PartitionCoordinator\u0027s __init__, but I didn\u0027t add the actual start call here. Obviously the unit tests aren\u0027t good enough yet if I could do that :-)","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d7ae67adf46fb811c0e3784bf24c52f791613424","unresolved":false,"context_lines":[{"line_number":170,"context_line":"                              initial_delay\u003dinterval if delay_start else None,"},{"line_number":171,"context_line":"                              task\u003dtask)"},{"line_number":172,"context_line":"        self.tg.add_timer(cfg.CONF.coordination.heartbeat,"},{"line_number":173,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @staticmethod"},{"line_number":176,"context_line":"    def interval_task(task):"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_d10a3f89","line":173,"updated":"2014-08-28 02:22:23.000000000","message":"I\u0027m thinking of moving this heartbeat timer into PartitionCoordinator.start() method, so the PartitionCoordinator is self-contained.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"ee99a05c2854b331379c92ff7b099e57c2a95d6a","unresolved":false,"context_lines":[{"line_number":170,"context_line":"                              initial_delay\u003dinterval if delay_start else None,"},{"line_number":171,"context_line":"                              task\u003dtask)"},{"line_number":172,"context_line":"        self.tg.add_timer(cfg.CONF.coordination.heartbeat,"},{"line_number":173,"context_line":"                          self.partition_coordinator.heartbeat)"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @staticmethod"},{"line_number":176,"context_line":"    def interval_task(task):"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_4f73e37f","line":173,"in_reply_to":"1abeadc6_d10a3f89","updated":"2014-08-28 07:23:26.000000000","message":"Yeah, I was thinking the same thing, but currently, the practice seems to be that all threads are handled by the service directly. This is also the way the partitioned alarm evaluator is implemented currently. But the approach is up to debate, of course.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"f625e1af9f4f2bfb481684b24cca4939969f6dfc","unresolved":false,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    def discover(self, discovery\u003dNone):"},{"line_number":191,"context_line":"        resources \u003d []"},{"line_number":192,"context_line":"        for url in (discovery or self.default_discovery):"},{"line_number":193,"context_line":"            name, param \u003d self._parse_discoverer(url)"},{"line_number":194,"context_line":"            discoverer \u003d self._discoverer(name)"},{"line_number":195,"context_line":"            if discoverer:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_7d522736","line":192,"updated":"2014-08-27 20:11:59.000000000","message":"both options are always empty for me when running central agent so it never actually figures out subset","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"ee99a05c2854b331379c92ff7b099e57c2a95d6a","unresolved":false,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    def discover(self, discovery\u003dNone):"},{"line_number":191,"context_line":"        resources \u003d []"},{"line_number":192,"context_line":"        for url in (discovery or self.default_discovery):"},{"line_number":193,"context_line":"            name, param \u003d self._parse_discoverer(url)"},{"line_number":194,"context_line":"            discoverer \u003d self._discoverer(name)"},{"line_number":195,"context_line":"            if discoverer:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_af6637b9","line":192,"in_reply_to":"1abeadc6_5611c550","updated":"2014-08-28 07:23:26.000000000","message":"Yep, we\u0027ll need to migrate all the pollsters to use discoveries first. I\u0027ll get busy right away.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d7ae67adf46fb811c0e3784bf24c52f791613424","unresolved":false,"context_lines":[{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    def discover(self, discovery\u003dNone):"},{"line_number":191,"context_line":"        resources \u003d []"},{"line_number":192,"context_line":"        for url in (discovery or self.default_discovery):"},{"line_number":193,"context_line":"            name, param \u003d self._parse_discoverer(url)"},{"line_number":194,"context_line":"            discoverer \u003d self._discoverer(name)"},{"line_number":195,"context_line":"            if discoverer:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_5611c550","line":192,"in_reply_to":"1abeadc6_7d522736","updated":"2014-08-28 02:22:23.000000000","message":"Not exactly, when running central agent polling metrics for lbaas/fwaas/tripleO hardware, we should have discover as defined in https://github.com/openstack/ceilometer/blob/master/setup.cfg#L81. But yeah, for other typical cases, these are empty now. \n\nAlso many central agent\u0027s pollsters don\u0027t use the \u0027resources\u0027 parameter in their get_samples method at all, instead they discover the resources they want to poll by their own. I think We need to make them use the \u0027resources\u0027 parameters. Otherwise, if we have multiple central agents running those pollsters, we\u0027ll see duplicated metrics being reported.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"}],"ceilometer/central/manager.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"b6fe56e8716186e75ef036d1ba18f86238e74d18","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_abc148e6","line":29,"updated":"2014-08-14 10:33:01.000000000","message":"Not sure what you mean by \"Their sets of resources *must* be disjoint.\"\n\nWould it be that for each sub-group of the central agent pool with the same partitioning_group_prefix, a disjoint subset of pollsters should be loaded?\n\ne.g. if I have prefixes configured of say:\n* partitioning_group_prefix\u003dsnmp\n* partitioning_group_prefix\u003dneutron\n* partitioning_group_prefix\u003dglance\n\nThe central agents with \"snmp-\" prefix should only load the hardware.* pollsters, whereas the central agents with the neutron- prefix should only load the {LB|FW|VPN}aaS pollsters, and so on?","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"e4b0302fdf4d7bc3945924492b002ffdb58b3462","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1abeadc6_8e366102","line":29,"in_reply_to":"7ac7a964_013a1bcd","updated":"2014-08-18 14:29:28.000000000","message":"Done","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"7a106a03aae61527c00824dc8bf1ab2cd3dbc5c5","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_013a1bcd","line":29,"in_reply_to":"7ac7a964_6e901eed","updated":"2014-08-14 10:53:32.000000000","message":"Ok, Nejc, thanks, I got it :)","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"732c56ac14926a3e72519e499e416055a5829778","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_aebf96cf","line":29,"in_reply_to":"7ac7a964_abc148e6","updated":"2014-08-14 10:39:46.000000000","message":"@Eoghan: That\u0027s exactly the use case I wanted to support with this option.\n\nQuoting Lianhao Lu from the spec comments: \"I\u0027m ok with this as long as we don\u0027t block some existing central agent usage model, i.e. different multiple central agents polling on different things.\"\n\n@Dina: this isn\u0027t the intended usage for the future, just supporting an old usage model for compatibility.","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"7e778fb8bd717dd3aceb18700a78466144385231","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_0ee7aa13","line":29,"in_reply_to":"7ac7a964_abc148e6","updated":"2014-08-14 10:36:44.000000000","message":"If so, I guess I don\u0027t actually like this idea - the option of agents working with different resources inside seems more HA for me - like one agent polls cpu and smth from snmp, second one some network info and some more hardware pollsters, etc.\n\nDo I miss something or misunderstand that?","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"f79f8c514a8f7629f778eb376e2f967168efc571","unresolved":false,"context_lines":[{"line_number":26,"context_line":"               default\u003dNone,"},{"line_number":27,"context_line":"               help\u003d\u0027Work-load partitioning group prefix. Use if you want \u0027"},{"line_number":28,"context_line":"                    \u0027multiple central agents with different config \u0027"},{"line_number":29,"context_line":"                    \u0027files. Their sets of resources *must* be disjoint.\u0027),"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027central\u0027)"},{"line_number":32,"context_line":"cfg.CONF.import_group(\u0027service_credentials\u0027, \u0027ceilometer.service\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_6e901eed","line":29,"in_reply_to":"7ac7a964_aebf96cf","updated":"2014-08-14 10:49:10.000000000","message":"A-ha, as a non-default transition mode, I think this is OK.\n\nSo basically the guidance would be to be use peer-agents loading all pollsters in the normal case.","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"}],"ceilometer/compute/discovery.py":[{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d7ae67adf46fb811c0e3784bf24c52f791613424","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    @property"},{"line_number":44,"context_line":"    def group_id(self):"},{"line_number":45,"context_line":"        if cfg.CONF.compute.workload_partitioning:"},{"line_number":46,"context_line":"            return cfg.CONF.host"},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_f6b3b197","line":46,"updated":"2014-08-28 02:22:23.000000000","message":"I\u0027m not sure why accessing this option not trigger an exception, since it\u0027s registered in service.py and not be imported here.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"ee99a05c2854b331379c92ff7b099e57c2a95d6a","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    @property"},{"line_number":44,"context_line":"    def group_id(self):"},{"line_number":45,"context_line":"        if cfg.CONF.compute.workload_partitioning:"},{"line_number":46,"context_line":"            return cfg.CONF.host"},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_8f009bac","line":46,"in_reply_to":"1abeadc6_f6b3b197","updated":"2014-08-28 07:23:26.000000000","message":"Not sure either, but it\u0027s been used before, in line #39, that\u0027s why it didn\u0027t even cross my mind to import it. Will fix.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"83feba56f75c7329c60a48273d3443794c221b16","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        if cfg.CONF.compute.workload_partitioning:"},{"line_number":46,"context_line":"            return cfg.CONF.host"},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_9dc97928","line":48,"updated":"2014-08-29 08:42:54.000000000","message":"I\u0027m wondering whether the compute agent change should be factored out to a small dependent patch, so as to keep this patch completely focused on the central agent (as per the linked BP).","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"6a91b1758f51d5c391318b6e9c099fda654c1056","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        if cfg.CONF.compute.workload_partitioning:"},{"line_number":46,"context_line":"            return cfg.CONF.host"},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_8c9789eb","line":48,"in_reply_to":"1abeadc6_9dc97928","updated":"2014-08-29 10:20:06.000000000","message":"Without this change, this patch would break compute agent. Compute agents on different nodes would end up in the same \u0027global\u0027 group and would incorrectly partition their resources.","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"}],"ceilometer/coordination.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"5a5f89fdea4c80f8f78f8a5fd264aa71434f8118","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo.config import cfg"},{"line_number":19,"context_line":"import tooz.coordination"},{"line_number":20,"context_line":"import uuid"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from ceilometer.openstack.common.gettextutils import _"},{"line_number":23,"context_line":"from ceilometer.openstack.common import log"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_70428411","line":20,"updated":"2014-08-19 13:52:17.000000000","message":"Wrong ordering of imports.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo.config import cfg"},{"line_number":19,"context_line":"import tooz.coordination"},{"line_number":20,"context_line":"import uuid"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from ceilometer.openstack.common.gettextutils import _"},{"line_number":23,"context_line":"from ceilometer.openstack.common import log"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_49fde839","line":20,"updated":"2014-08-19 14:20:12.000000000","message":"move uuid above to it\u0027s own group","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"OPTS \u003d ["},{"line_number":29,"context_line":"    cfg.StrOpt(\u0027backend_url\u0027,"},{"line_number":30,"context_line":"               default\u003dNone,"},{"line_number":31,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination\u0027),"},{"line_number":32,"context_line":"    cfg.FloatOpt(\u0027heartbeat\u0027,"},{"line_number":33,"context_line":"                 default\u003d1.0,"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_e9a3144d","line":30,"updated":"2014-08-19 14:20:12.000000000","message":"just curious? what does backend None mean?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"OPTS \u003d ["},{"line_number":29,"context_line":"    cfg.StrOpt(\u0027backend_url\u0027,"},{"line_number":30,"context_line":"               default\u003dNone,"},{"line_number":31,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination\u0027),"},{"line_number":32,"context_line":"    cfg.FloatOpt(\u0027heartbeat\u0027,"},{"line_number":33,"context_line":"                 default\u003d1.0,"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_77217ab3","line":30,"in_reply_to":"1abeadc6_e9a3144d","updated":"2014-08-20 06:00:43.000000000","message":"That the backend is not configured and there shouldn\u0027t be any workload partitioning going on (e.g. get_my_subset returns the full unfiltered iterable). I\u0027ll make that clear in the help message.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"d9ef10805e197ecdc6690bcca4ed75a5d46f88ca","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    This class uses the `tooz` library to manage group membership."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    To ensure that the other agents know we\u0027re alive, the `heartbeat` method"},{"line_number":46,"context_line":"    should be called periodically."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    Coordination errors and reconnects are handled under the hood, so the"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_666e2a98","line":45,"range":{"start_line":45,"start_character":41,"end_line":45,"end_character":43},"updated":"2014-08-20 08:38:28.000000000","message":"we\u0027re -\u003e I\u0027m ? as we changed we -\u003e I in the code","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"980d7cae24c580f7c922ae153ca4e18ecddc5348","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    This class uses the `tooz` library to manage group membership."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    To ensure that the other agents know we\u0027re alive, the `heartbeat` method"},{"line_number":46,"context_line":"    should be called periodically."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    Coordination errors and reconnects are handled under the hood, so the"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_66f46a87","line":45,"in_reply_to":"1abeadc6_666e2a98","updated":"2014-08-20 08:48:15.000000000","message":"I\u0027ll clarify this by \u0027.. other agents know this agent is alive ...\u0027. \u0027I\u0027 doesn\u0027t look good to me in this context.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"ef1ddb84d6af0b5bf5d0f97ea94010709de1ade0","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    This class uses the `tooz` library to manage group membership."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    To ensure that the other agents know we\u0027re alive, the `heartbeat` method"},{"line_number":46,"context_line":"    should be called periodically."},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    Coordination errors and reconnects are handled under the hood, so the"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_46268ecf","line":45,"in_reply_to":"1abeadc6_66f46a87","updated":"2014-08-20 08:59:30.000000000","message":"a-ha, cool, sorry, I missed that :)","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                self._started \u003d True"},{"line_number":68,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":69,"context_line":"                self._started \u003d False"},{"line_number":70,"context_line":"                LOG.exception(_(\u0027Error connecting to coordination backend.\u0027))"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def my_id(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_cdaae3d1","line":70,"updated":"2014-08-19 14:20:12.000000000","message":"_LE(\u0027Error...\n\nprobably better to expose error as well. ie tooz.coordination.ToozError as e... yada yada yada..","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                self._started \u003d True"},{"line_number":68,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":69,"context_line":"                self._started \u003d False"},{"line_number":70,"context_line":"                LOG.exception(_(\u0027Error connecting to coordination backend.\u0027))"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def my_id(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_b754f221","line":70,"in_reply_to":"1abeadc6_cdaae3d1","updated":"2014-08-20 06:00:43.000000000","message":"Done","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def my_id(self):"},{"line_number":74,"context_line":"        return self._my_id"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    def is_active(self):"},{"line_number":77,"context_line":"        return self._coordinator is not None"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_4d0973dc","line":74,"updated":"2014-08-19 14:20:12.000000000","message":"what\u0027s the point of this property? it doesn\u0027t seem to be use anywhere outside of class.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def my_id(self):"},{"line_number":74,"context_line":"        return self._my_id"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    def is_active(self):"},{"line_number":77,"context_line":"        return self._coordinator is not None"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_9759b65c","line":74,"in_reply_to":"1abeadc6_4d0973dc","updated":"2014-08-20 06:00:43.000000000","message":"You\u0027re right, it\u0027s a remnant of a previous approach. Removing.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                # re-connect"},{"line_number":83,"context_line":"                self.start()"},{"line_number":84,"context_line":"            try:"},{"line_number":85,"context_line":"                self._coordinator.heartbeat()"},{"line_number":86,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":87,"context_line":"                LOG.exception(_(\u0027Error sending a heartbeat to coordination \u0027"},{"line_number":88,"context_line":"                                \u0027backend.\u0027))"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_d091989b","line":85,"updated":"2014-08-19 14:20:12.000000000","message":"does this actually raise a ToozError? i\u0027m not sure the memcache driver does... does zookeeper raise it?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                # re-connect"},{"line_number":83,"context_line":"                self.start()"},{"line_number":84,"context_line":"            try:"},{"line_number":85,"context_line":"                self._coordinator.heartbeat()"},{"line_number":86,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":87,"context_line":"                LOG.exception(_(\u0027Error sending a heartbeat to coordination \u0027"},{"line_number":88,"context_line":"                                \u0027backend.\u0027))"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_9a639bdb","line":85,"in_reply_to":"1abeadc6_d091989b","updated":"2014-08-20 06:00:43.000000000","message":"memcache driver is currently not as dilligent as the zookeeper driver in handling errors, but I think each tooz action should potentially raise a ToozError (if the backend raises an unexpected exception). Zookeeper driver does so (it has no heartbeat method though), memcache - not yet.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                self._coordinator.heartbeat()"},{"line_number":86,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":87,"context_line":"                LOG.exception(_(\u0027Error sending a heartbeat to coordination \u0027"},{"line_number":88,"context_line":"                                \u0027backend.\u0027))"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def join_group(self, group_id):"},{"line_number":91,"context_line":"        if not self._coordinator or not self._started or not group_id:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_cdc5833e","line":88,"updated":"2014-08-19 14:20:12.000000000","message":"same thing, expose error and _LE","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"d9ef10805e197ecdc6690bcca4ed75a5d46f88ca","unresolved":false,"context_lines":[{"line_number":99,"context_line":"            except tooz.coordination.MemberAlreadyExist:"},{"line_number":100,"context_line":"                return"},{"line_number":101,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":102,"context_line":"                create_grp_req \u003d self._coordinator.create_group(group_id)"},{"line_number":103,"context_line":"                try:"},{"line_number":104,"context_line":"                    create_grp_req.get()"},{"line_number":105,"context_line":"                except tooz.coordination.GroupAlreadyExist:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_a6eda2f1","line":102,"range":{"start_line":102,"start_character":16,"end_line":102,"end_character":30},"updated":"2014-08-20 08:38:28.000000000","message":"not sure, but in this try:except sections I see logic like\n\n- join group\n- try to add group to my ones\n   - if it was added already, break\n   - if if was not created, create\n\nBu I don\u0027t see if after group creation it was added. Is it ok?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"ef1ddb84d6af0b5bf5d0f97ea94010709de1ade0","unresolved":false,"context_lines":[{"line_number":99,"context_line":"            except tooz.coordination.MemberAlreadyExist:"},{"line_number":100,"context_line":"                return"},{"line_number":101,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":102,"context_line":"                create_grp_req \u003d self._coordinator.create_group(group_id)"},{"line_number":103,"context_line":"                try:"},{"line_number":104,"context_line":"                    create_grp_req.get()"},{"line_number":105,"context_line":"                except tooz.coordination.GroupAlreadyExist:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_3a144243","line":102,"in_reply_to":"1abeadc6_86dc2614","updated":"2014-08-20 08:59:30.000000000","message":"a-ha, thanks for the clarification, I just did not get it from the first look","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"980d7cae24c580f7c922ae153ca4e18ecddc5348","unresolved":false,"context_lines":[{"line_number":99,"context_line":"            except tooz.coordination.MemberAlreadyExist:"},{"line_number":100,"context_line":"                return"},{"line_number":101,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":102,"context_line":"                create_grp_req \u003d self._coordinator.create_group(group_id)"},{"line_number":103,"context_line":"                try:"},{"line_number":104,"context_line":"                    create_grp_req.get()"},{"line_number":105,"context_line":"                except tooz.coordination.GroupAlreadyExist:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_86dc2614","line":102,"in_reply_to":"1abeadc6_a6eda2f1","updated":"2014-08-20 08:48:15.000000000","message":"It\u0027s actually the \u0027join_req.get()\u0027 part of joining a group in tooz that raises the exceptions. I should put the actual call to join_group() into the try as well, for more clarity.\n\nIf we try to join a nonexistent group, the exception is caught and the group is joined. But in this case the loop isn\u0027t broken out of, so we continue into another iteration of the \u0027while True\u0027 loop. When joining a group finally succeeds, we break out.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                    create_grp_req.get()"},{"line_number":105,"context_line":"                except tooz.coordination.GroupAlreadyExist:"},{"line_number":106,"context_line":"                    pass"},{"line_number":107,"context_line":"                continue"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def _get_members(self, group_id):"},{"line_number":110,"context_line":"        if not self._coordinator:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_508ca835","line":107,"updated":"2014-08-19 14:20:12.000000000","message":"i\u0027m not sure there\u0027s a point to this continue?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                    create_grp_req.get()"},{"line_number":105,"context_line":"                except tooz.coordination.GroupAlreadyExist:"},{"line_number":106,"context_line":"                    pass"},{"line_number":107,"context_line":"                continue"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def _get_members(self, group_id):"},{"line_number":110,"context_line":"        if not self._coordinator:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_1a7eab6b","line":107,"in_reply_to":"1abeadc6_508ca835","updated":"2014-08-20 06:00:43.000000000","message":"Nope, there isn\u0027t anymore.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            return [self._my_id]"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        while True:"},{"line_number":114,"context_line":"            get_members_req \u003d self._coordinator.get_members(group_id)"},{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_10687086","line":114,"updated":"2014-08-19 14:20:12.000000000","message":"i think get_members will raise GroupNotCreated\n\nhttps://github.com/stackforge/tooz/blob/d38fe0301d991300a29ab09175f110356fe47653/tooz/drivers/memcached.py#L217-L222","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            return [self._my_id]"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        while True:"},{"line_number":114,"context_line":"            get_members_req \u003d self._coordinator.get_members(group_id)"},{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_9ae8fb11","line":114,"in_reply_to":"1abeadc6_10687086","updated":"2014-08-20 06:00:43.000000000","message":"That\u0027s the worker function, in\n\nhttps://github.com/stackforge/tooz/blob/d38fe0301d991300a29ab09175f110356fe47653/tooz/drivers/memcached.py#L224\n\n, the exception is wrapped in an async result.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"3e3406d7466d735492281a8eaa0e9cd539e22190","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            return [self._my_id]"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        while True:"},{"line_number":114,"context_line":"            get_members_req \u003d self._coordinator.get_members(group_id)"},{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_455d9146","line":114,"in_reply_to":"1abeadc6_9ae8fb11","updated":"2014-08-20 17:54:48.000000000","message":"touche","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":118,"context_line":"                self.join_group(group_id)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def get_my_subset(self, group_id, iterable):"},{"line_number":121,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to this agent."}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_700d2490","line":118,"updated":"2014-08-19 14:20:12.000000000","message":"will this situation ever occur? based on get_my_subset below, it\u0027ll always call join_group before _get_members so i would think the group would always exist?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":118,"context_line":"                self.join_group(group_id)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def get_my_subset(self, group_id, iterable):"},{"line_number":121,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to this agent."}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_da38b3a2","line":118,"in_reply_to":"1abeadc6_700d2490","updated":"2014-08-20 06:00:43.000000000","message":"It\u0027s a distributed system and we don\u0027t have transactions. Someone might delete a group right after we joined it. Isn\u0027t it best to recover gracefully from as many situations as possible?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"3e3406d7466d735492281a8eaa0e9cd539e22190","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return get_members_req.get()"},{"line_number":117,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":118,"context_line":"                self.join_group(group_id)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def get_my_subset(self, group_id, iterable):"},{"line_number":121,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to this agent."}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_0548f985","line":118,"in_reply_to":"1abeadc6_da38b3a2","updated":"2014-08-20 17:54:48.000000000","message":"touche","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":134,"context_line":"            return [v for v in iterable"},{"line_number":135,"context_line":"                    if hr.get_node(str(v)) \u003d\u003d self.my_id]"},{"line_number":136,"context_line":"        except tooz.coordination.ToozError:"},{"line_number":137,"context_line":"            LOG.exception(_(\u0027Error getting group membership info from \u0027"},{"line_number":138,"context_line":"                            \u0027coordination backend.\u0027))"},{"line_number":139,"context_line":"            return []"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_f02054f9","line":137,"updated":"2014-08-19 14:20:12.000000000","message":"_LE(....)","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"df01c0fdb81c422865c45288cff4459563044576","unresolved":false,"context_lines":[{"line_number":80,"context_line":"        if self._coordinator:"},{"line_number":81,"context_line":"            if not self._started:"},{"line_number":82,"context_line":"                # re-connect"},{"line_number":83,"context_line":"                self.start()"},{"line_number":84,"context_line":"            try:"},{"line_number":85,"context_line":"                self._coordinator.heartbeat()"},{"line_number":86,"context_line":"            except tooz.coordination.ToozError:"}],"source_content_type":"text/x-python","patch_set":7,"id":"1abeadc6_a9b9d716","line":83,"updated":"2014-08-20 21:34:06.000000000","message":"maybe i\u0027m not configuring this right but there seems to be a logic error or a missing start() call... this seems to be the only place that starts the coordinator... but this never gets called since the coordinator is set in start()...which again never gets called.","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"5109c691e391d0607657a249e69d79b244decc62","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    cfg.StrOpt(\u0027backend_url\u0027,"},{"line_number":31,"context_line":"               default\u003dNone,"},{"line_number":32,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination. If \u0027"},{"line_number":33,"context_line":"                    \u0027left empty, certain services won\\\u0027t do workload \u0027"},{"line_number":34,"context_line":"                    \u0027partitioning and will only function correctly if a \u0027"},{"line_number":35,"context_line":"                    \u0027single instance of that service is running.\u0027),"},{"line_number":36,"context_line":"    cfg.FloatOpt(\u0027heartbeat\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"1abeadc6_a66baf1c","line":33,"range":{"start_line":33,"start_character":53,"end_line":33,"end_character":54},"updated":"2014-08-21 12:07:23.000000000","message":"remove \\","commit_id":"f1c3fa493004d9834ab384e979702fe1ff4c5dc1"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"4ffbe386741029c4c026615079eb2c19a4e62d9b","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    cfg.StrOpt(\u0027backend_url\u0027,"},{"line_number":31,"context_line":"               default\u003dNone,"},{"line_number":32,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination. If \u0027"},{"line_number":33,"context_line":"                    \u0027left empty, certain services won\\\u0027t do workload \u0027"},{"line_number":34,"context_line":"                    \u0027partitioning and will only function correctly if a \u0027"},{"line_number":35,"context_line":"                    \u0027single instance of that service is running.\u0027),"},{"line_number":36,"context_line":"    cfg.FloatOpt(\u0027heartbeat\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"1abeadc6_625dfa14","line":33,"range":{"start_line":33,"start_character":53,"end_line":33,"end_character":54},"in_reply_to":"1abeadc6_a66baf1c","updated":"2014-08-21 15:37:44.000000000","message":"oh, sorry, did not understand what it was for","commit_id":"f1c3fa493004d9834ab384e979702fe1ff4c5dc1"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"2cec40f55c7d4738918e8a4f0b760c5f7b40ffe2","unresolved":false,"context_lines":[{"line_number":41,"context_line":"cfg.CONF.register_opts(OPTS, group\u003d\u0027coordination\u0027)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class PartitionCoordinator:"},{"line_number":45,"context_line":"    \"\"\"Workload partitioning coordinator."},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    This class uses the `tooz` library to manage group membership."}],"source_content_type":"text/x-python","patch_set":11,"id":"1abeadc6_46249b5f","line":44,"updated":"2014-08-21 12:00:38.000000000","message":"please use PartitionCoordinator(object):","commit_id":"f1c3fa493004d9834ab384e979702fe1ff4c5dc1"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"83feba56f75c7329c60a48273d3443794c221b16","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    cfg.StrOpt(\u0027backend_url\u0027,"},{"line_number":31,"context_line":"               default\u003dNone,"},{"line_number":32,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination. If \u0027"},{"line_number":33,"context_line":"                    \u0027left empty, certain services won\\\u0027t do workload \u0027"},{"line_number":34,"context_line":"                    \u0027partitioning and will only function correctly if a \u0027"},{"line_number":35,"context_line":"                    \u0027single instance of that service is running.\u0027),"},{"line_number":36,"context_line":"    cfg.FloatOpt(\u0027heartbeat\u0027,"}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_19d9fe56","line":33,"updated":"2014-08-29 08:42:54.000000000","message":"How about being more specific in the help string as what the \u0027certain services\u0027 are, since this would never impact on say the collector, notification agent or API service (so it would not to give the impression to a newbie that it applies across the board).\n\nHow about:\n\n  s/certain services/the per-deployment central agent and per-host compute agent/","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"83feba56f75c7329c60a48273d3443794c221b16","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":120,"context_line":"                self.join_group(group_id)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    def get_my_subset(self, group_id, iterable):"},{"line_number":123,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to this agent."},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_fd3c2de3","line":122,"updated":"2014-08-29 08:42:54.000000000","message":"Just a suggestion, would filter_my_subset() be a readable alternative method name here? So as to emphasize the filtering, as opposed to the retrieval, aspect.\n\n(Feel free to ignore ...)","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"6a91b1758f51d5c391318b6e9c099fda654c1056","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            except tooz.coordination.GroupNotCreated:"},{"line_number":120,"context_line":"                self.join_group(group_id)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    def get_my_subset(self, group_id, iterable):"},{"line_number":123,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to this agent."},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_d7074a16","line":122,"in_reply_to":"1abeadc6_fd3c2de3","updated":"2014-08-29 10:20:06.000000000","message":"After debate on IRC, we\u0027ll change this to extract_my_subset","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"33513b25131cd6fb8b932d59130c4bb0feda36e3","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                self.start()"},{"line_number":86,"context_line":"            try:"},{"line_number":87,"context_line":"                self._coordinator.heartbeat()"},{"line_number":88,"context_line":"                LOG.debug(\u0027Sending heartbeat to coordination backend.\u0027)"},{"line_number":89,"context_line":"            except tooz.coordination.ToozError:"},{"line_number":90,"context_line":"                LOG.exception(_LE(\u0027Error sending a heartbeat to coordination \u0027"},{"line_number":91,"context_line":"                                  \u0027backend.\u0027))"}],"source_content_type":"text/x-python","patch_set":20,"id":"1abeadc6_f2960a4b","line":88,"updated":"2014-08-29 15:40:11.000000000","message":"we should remove this.","commit_id":"8004ff20de225ea186d6e943d1df7650116af2e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"33513b25131cd6fb8b932d59130c4bb0feda36e3","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        try:"},{"line_number":136,"context_line":"            members \u003d self._get_members(group_id)"},{"line_number":137,"context_line":"            LOG.debug(\u0027Members of group: %s\u0027, members)"},{"line_number":138,"context_line":"            LOG.debug(\u0027Iterable: %s\u0027, iterable)"},{"line_number":139,"context_line":"            hr \u003d utils.HashRing(members)"},{"line_number":140,"context_line":"            filtered \u003d [v for v in iterable"},{"line_number":141,"context_line":"                        if hr.get_node(str(v)) \u003d\u003d self._my_id]"}],"source_content_type":"text/x-python","patch_set":20,"id":"1abeadc6_d283ce00","line":138,"updated":"2014-08-29 15:40:11.000000000","message":"we can probably remove this Iterable log too.","commit_id":"8004ff20de225ea186d6e943d1df7650116af2e0"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"3f63ae7c357c67840e9710231e6e75885e6c52f8","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        the ones that hashed into *our* bucket."},{"line_number":128,"context_line":"        \"\"\""},{"line_number":129,"context_line":"        if not group_id:"},{"line_number":130,"context_line":"            LOG.debug(\u0027No group id defined, returning the whole iterable.\u0027)"},{"line_number":131,"context_line":"            return iterable"},{"line_number":132,"context_line":"        if group_id not in self._groups:"},{"line_number":133,"context_line":"            self.join_group(group_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"1abeadc6_581a787d","line":130,"updated":"2014-08-29 19:10:21.000000000","message":"do we care to have this print every interval?","commit_id":"6b9b5168888de304147ef86b285bb4bc9c06d318"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"3f63ae7c357c67840e9710231e6e75885e6c52f8","unresolved":false,"context_lines":[{"line_number":133,"context_line":"            self.join_group(group_id)"},{"line_number":134,"context_line":"        try:"},{"line_number":135,"context_line":"            members \u003d self._get_members(group_id)"},{"line_number":136,"context_line":"            LOG.debug(\u0027Members of group: %s\u0027, members)"},{"line_number":137,"context_line":"            hr \u003d utils.HashRing(members)"},{"line_number":138,"context_line":"            filtered \u003d [v for v in iterable"},{"line_number":139,"context_line":"                        if hr.get_node(str(v)) \u003d\u003d self._my_id]"}],"source_content_type":"text/x-python","patch_set":21,"id":"1abeadc6_38285c96","line":136,"updated":"2014-08-29 19:10:21.000000000","message":"same","commit_id":"6b9b5168888de304147ef86b285bb4bc9c06d318"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"3f63ae7c357c67840e9710231e6e75885e6c52f8","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            hr \u003d utils.HashRing(members)"},{"line_number":138,"context_line":"            filtered \u003d [v for v in iterable"},{"line_number":139,"context_line":"                        if hr.get_node(str(v)) \u003d\u003d self._my_id]"},{"line_number":140,"context_line":"            LOG.debug(\u0027My subset: %s\u0027, filtered)"},{"line_number":141,"context_line":"            return filtered"},{"line_number":142,"context_line":"        except tooz.coordination.ToozError:"},{"line_number":143,"context_line":"            LOG.exception(_LE(\u0027Error getting group membership info from \u0027"}],"source_content_type":"text/x-python","patch_set":21,"id":"1abeadc6_d80da83f","line":140,"updated":"2014-08-29 19:10:21.000000000","message":"same","commit_id":"6b9b5168888de304147ef86b285bb4bc9c06d318"}],"ceilometer/partitioning.py":[{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"585f5b5527a26403179fb0d3cdc1a928fd02dc22","unresolved":false,"context_lines":[{"line_number":31,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination\u0027),"},{"line_number":32,"context_line":"    cfg.FloatOpt(\u0027coordination_heartbeat\u0027,"},{"line_number":33,"context_line":"                 default\u003d0.1,"},{"line_number":34,"context_line":"                 help\u003d\u0027The time between heartbeats for distributed \u0027"},{"line_number":35,"context_line":"                      \u0027coordination\u0027)"},{"line_number":36,"context_line":"]"},{"line_number":37,"context_line":"cfg.CONF.register_opts(OPTS)"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_06fa1811","line":34,"updated":"2014-08-13 14:25:36.000000000","message":"please set unit of time measurement here in the help message - just to be sure we speak about the same time intervals","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f6149994a14ec249c8b587e62753de8ca31b8222","unresolved":false,"context_lines":[{"line_number":31,"context_line":"               help\u003d\u0027The backend URL to use for distributed coordination\u0027),"},{"line_number":32,"context_line":"    cfg.FloatOpt(\u0027coordination_heartbeat\u0027,"},{"line_number":33,"context_line":"                 default\u003d0.1,"},{"line_number":34,"context_line":"                 help\u003d\u0027The time between heartbeats for distributed \u0027"},{"line_number":35,"context_line":"                      \u0027coordination\u0027)"},{"line_number":36,"context_line":"]"},{"line_number":37,"context_line":"cfg.CONF.register_opts(OPTS)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_8d658747","line":34,"in_reply_to":"baada198_06fa1811","updated":"2014-08-14 10:15:59.000000000","message":"Done","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"139e333d4f4d46880d3f1776366ac08424955fcf","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        else:"},{"line_number":92,"context_line":"            return [self._our_id]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def get_our_subset(self, group_id, iterable):"},{"line_number":95,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to us."},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_6c0f35e1","line":94,"updated":"2014-08-13 15:15:59.000000000","message":"I like this naming approach. But might it be slightly clearer in the first person singular:\n\n  def my_id(self, ...)\n  def get_my_subset(self, ...)\n\nso as to clearly distinguish the *individual* agent from the group?","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"f29f2f04dcd93e4456e743ca6dd39240e34aff69","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        else:"},{"line_number":92,"context_line":"            return [self._our_id]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def get_our_subset(self, group_id, iterable):"},{"line_number":95,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to us."},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_6f9f2703","line":94,"in_reply_to":"baada198_6c0f35e1","updated":"2014-08-13 15:27:35.000000000","message":"btw, that\u0027s a good idea - I spent some time trying to understand who\u0027s \u0027we\u0027 here - I guess \u0027my\u0027 will be better","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"97563449559ba878c1dda7ab07b16037a83ed57a","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        else:"},{"line_number":92,"context_line":"            return [self._our_id]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def get_our_subset(self, group_id, iterable):"},{"line_number":95,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to us."},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_a0806c9d","line":94,"in_reply_to":"baada198_6f9f2703","updated":"2014-08-13 16:22:41.000000000","message":"Sure thing, I agree!","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f6149994a14ec249c8b587e62753de8ca31b8222","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        else:"},{"line_number":92,"context_line":"            return [self._our_id]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def get_our_subset(self, group_id, iterable):"},{"line_number":95,"context_line":"        \"\"\"Filters an iterable, returning only objects assigned to us."},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        We have a list of objects and get a list of active group members from"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_ad5a4381","line":94,"in_reply_to":"baada198_a0806c9d","updated":"2014-08-14 10:15:59.000000000","message":"Done","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"4ce3ea99cea5662faa59804cb03e265df7a82dc2","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            return iterable"},{"line_number":103,"context_line":"        if group_id not in self._groups:"},{"line_number":104,"context_line":"            self.join_group(group_id)"},{"line_number":105,"context_line":"        members \u003d self._get_members(group_id)"},{"line_number":106,"context_line":"        our_key \u003d sorted(members).index(self.my_id)"},{"line_number":107,"context_line":"        return [v for v in iterable"},{"line_number":108,"context_line":"                if int(hashlib.md5(str(v)).hexdigest(), 16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_63f8137d","line":105,"updated":"2014-08-15 01:29:53.000000000","message":"How does this work when the group size changed right after this _get_members returned? What stops the group size from changing during this period, or during iteration? What stops the ids from being in different sort orders (afaik uuid.uuid4 is a random uuid)?\n\nU might strongly want to look into using consistent hashing instead.\n\nhttps://pypi.python.org/pypi/hash_ring (or other library) to avoid these kind of size change issues (although using anything but a static-map won\u0027t likely fix this problem). If you don\u0027t and the group size changes during iteration (whats to stop it from changing size?) certain members will get other members items and the whole thing will be wonky. Depending on sort order  and group size (both things that can change dynamically) to avoid this problem just seems extremely fragile.","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b4496f578ad7072a1a36e4cbde410bce4ec3fe8a","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            return iterable"},{"line_number":103,"context_line":"        if group_id not in self._groups:"},{"line_number":104,"context_line":"            self.join_group(group_id)"},{"line_number":105,"context_line":"        members \u003d self._get_members(group_id)"},{"line_number":106,"context_line":"        our_key \u003d sorted(members).index(self.my_id)"},{"line_number":107,"context_line":"        return [v for v in iterable"},{"line_number":108,"context_line":"                if int(hashlib.md5(str(v)).hexdigest(), 16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_235b7b88","line":105,"updated":"2014-08-15 01:30:25.000000000","message":"Whats to stop the group from having been deleted, is this code expected to handle the group being removed (and _get_members failing)?","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"e4b0302fdf4d7bc3945924492b002ffdb58b3462","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            return iterable"},{"line_number":103,"context_line":"        if group_id not in self._groups:"},{"line_number":104,"context_line":"            self.join_group(group_id)"},{"line_number":105,"context_line":"        members \u003d self._get_members(group_id)"},{"line_number":106,"context_line":"        our_key \u003d sorted(members).index(self.my_id)"},{"line_number":107,"context_line":"        return [v for v in iterable"},{"line_number":108,"context_line":"                if int(hashlib.md5(str(v)).hexdigest(), 16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1abeadc6_398d957c","line":105,"in_reply_to":"7ac7a964_235b7b88","updated":"2014-08-18 14:29:28.000000000","message":"Done","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"22df8f5d1313c0d8aa74e001651d514bc9adc55d","unresolved":false,"context_lines":[{"line_number":102,"context_line":"            return iterable"},{"line_number":103,"context_line":"        if group_id not in self._groups:"},{"line_number":104,"context_line":"            self.join_group(group_id)"},{"line_number":105,"context_line":"        members \u003d self._get_members(group_id)"},{"line_number":106,"context_line":"        our_key \u003d sorted(members).index(self.my_id)"},{"line_number":107,"context_line":"        return [v for v in iterable"},{"line_number":108,"context_line":"                if int(hashlib.md5(str(v)).hexdigest(), 16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7ac7a964_ca6e4801","line":105,"in_reply_to":"7ac7a964_235b7b88","updated":"2014-08-15 13:58:38.000000000","message":"Good point, I\u0027ll add some sanity checking.","commit_id":"9cbe54771237adca29afe0bf6f3364c7c13d1ae0"}],"ceilometer/plugin.py":[{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"5697dc8eb2c8530535b08edd9760c63b9be14b43","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        discoveries. A None value signifies that this discovery does not"},{"line_number":162,"context_line":"        want to be part of workload partitioning at all."},{"line_number":163,"context_line":"        \"\"\""},{"line_number":164,"context_line":"        return \u0027global\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_d08438b3","line":164,"updated":"2014-08-19 14:20:12.000000000","message":"what does a \u0027global\u0027 value signify?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f1f4dd41e06c36fff4ab5b384c5313cbe680cab6","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        discoveries. A None value signifies that this discovery does not"},{"line_number":162,"context_line":"        want to be part of workload partitioning at all."},{"line_number":163,"context_line":"        \"\"\""},{"line_number":164,"context_line":"        return \u0027global\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_9a563bd1","line":164,"in_reply_to":"1abeadc6_d08438b3","updated":"2014-08-20 06:00:43.000000000","message":"It\u0027s a default group for discoveries, named \u0027global\u0027 (actually, it\u0027s central-agent-global by the time it gets to tooz). All discoveries are in this group by default, but they can override this to form their own groups, for example all network discoveries in Region One form a group \u0027network-region1\u0027.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"}],"ceilometer/tests/test_coordination.py":[{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"dba8041bbd9b303f67ced8748546581fd61d3fe5","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from ceilometer import coordination"},{"line_number":23,"context_line":"from ceilometer.openstack.common.fixture import config"},{"line_number":24,"context_line":"from ceilometer.openstack.common import test"},{"line_number":25,"context_line":"from ceilometer import utils"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1abeadc6_5ed505e3","line":24,"updated":"2014-08-22 20:13:58.000000000","message":"now this lib should be taken from oslo.test import base","commit_id":"c6ae9b5239642b7a5adf8b8f5d43a4508ffc6561"}],"ceilometer/tests/test_partitioning.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"139e333d4f4d46880d3f1776366ac08424955fcf","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        self.wait_group_init.add()"},{"line_number":146,"context_line":"        self.wait_group_finish.add()"},{"line_number":147,"context_line":"        return eventlet.spawn(worker, *args, **kwargs)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def test_single_group(self):"},{"line_number":150,"context_line":"        self._usage_simulation(\u0027agent1\u0027, \u0027group\u0027, [], [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_cf175345","line":147,"updated":"2014-08-13 15:15:59.000000000","message":"Would it be possible to reconstruct this test so that it doesn\u0027t require a thread to be spawned?","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f6149994a14ec249c8b587e62753de8ca31b8222","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        self.wait_group_init.add()"},{"line_number":146,"context_line":"        self.wait_group_finish.add()"},{"line_number":147,"context_line":"        return eventlet.spawn(worker, *args, **kwargs)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def test_single_group(self):"},{"line_number":150,"context_line":"        self._usage_simulation(\u0027agent1\u0027, \u0027group\u0027, [], [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"7ac7a964_cd5f7f71","line":147,"in_reply_to":"baada198_8d36404e","updated":"2014-08-14 10:15:59.000000000","message":"Done","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"97563449559ba878c1dda7ab07b16037a83ed57a","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        self.wait_group_init.add()"},{"line_number":146,"context_line":"        self.wait_group_finish.add()"},{"line_number":147,"context_line":"        return eventlet.spawn(worker, *args, **kwargs)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def test_single_group(self):"},{"line_number":150,"context_line":"        self._usage_simulation(\u0027agent1\u0027, \u0027group\u0027, [], [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_e0dc24e4","line":147,"in_reply_to":"baada198_cf175345","updated":"2014-08-13 16:22:41.000000000","message":"Quite possibly, yes, this is a remnant of the decorator approach, I think it could be avoided here.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"083c916435235f0c1bfe9bf3ce1bfc4638a7ab7f","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        self.wait_group_init.add()"},{"line_number":146,"context_line":"        self.wait_group_finish.add()"},{"line_number":147,"context_line":"        return eventlet.spawn(worker, *args, **kwargs)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"    def test_single_group(self):"},{"line_number":150,"context_line":"        self._usage_simulation(\u0027agent1\u0027, \u0027group\u0027, [], [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_8d36404e","line":147,"in_reply_to":"baada198_e0dc24e4","updated":"2014-08-13 17:11:21.000000000","message":"Cool.","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"}],"ceilometer/utils.py":[{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"d9ef10805e197ecdc6690bcca4ed75a5d46f88ca","unresolved":false,"context_lines":[{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def get_node(self, key):"},{"line_number":212,"context_line":"        if not self._ring:"},{"line_number":213,"context_line":"            return None"},{"line_number":214,"context_line":"        pos \u003d self._get_position_on_ring(key)"},{"line_number":215,"context_line":"        return self._ring[self._sorted_keys[pos]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_86ba6621","line":213,"updated":"2014-08-20 08:38:28.000000000","message":"possibly just return will look better here? it\u0027ll return None as well. Or do you like to do that explicitly?","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"ef1ddb84d6af0b5bf5d0f97ea94010709de1ade0","unresolved":false,"context_lines":[{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def get_node(self, key):"},{"line_number":212,"context_line":"        if not self._ring:"},{"line_number":213,"context_line":"            return None"},{"line_number":214,"context_line":"        pos \u003d self._get_position_on_ring(key)"},{"line_number":215,"context_line":"        return self._ring[self._sorted_keys[pos]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_5a3d7eba","line":213,"in_reply_to":"1abeadc6_864a66c3","updated":"2014-08-20 08:59:30.000000000","message":"ok, cool, that\u0027s just the question of the personal taste I think. Personally I always skip Nones where possible, but I suppose that your variant is better in this case :)","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"980d7cae24c580f7c922ae153ca4e18ecddc5348","unresolved":false,"context_lines":[{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    def get_node(self, key):"},{"line_number":212,"context_line":"        if not self._ring:"},{"line_number":213,"context_line":"            return None"},{"line_number":214,"context_line":"        pos \u003d self._get_position_on_ring(key)"},{"line_number":215,"context_line":"        return self._ring[self._sorted_keys[pos]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1abeadc6_864a66c3","line":213,"in_reply_to":"1abeadc6_86ba6621","updated":"2014-08-20 08:48:15.000000000","message":"Yes, because this code is \u0027supposed\u0027 to return something - it\u0027s not a void method, so to speak. I think it is more clear that it\u0027s explicitly stated that None is returned when the ring doesn\u0027t exist.","commit_id":"5dd1c0203f5f9f95a060e863441e9da9a6af62e0"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"af4c1911c6a9fe7f0a96c0371a771b92e2e8d8d8","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1abeadc6_f3367551","line":189,"updated":"2014-08-20 10:56:54.000000000","message":"I may be missing some context, but is the intent to promote this hash-ring implementation up to Oslo, or is it a bit to specific to the ceilometer requirement to be shared by Ironic?\n\n(BTW such promotion would not have to block this patch from landing ... i.e. it would be fine IMO to go ahead as-is with the intent to propose promotion via subsequent patches to oslo, ceilometer \u0026 ironic)","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"e45782849416e5f759bccf197a9754ea8b45a2c3","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1abeadc6_53fe4939","line":189,"in_reply_to":"1abeadc6_f3367551","updated":"2014-08-20 11:02:26.000000000","message":"Context:\n\n* hash_ring on PyPi is unmaintained\n* hash_ring implementation in Ironic is not really consistent hashing. If we use Ironic\u0027s code, it will be no better than using basic hashing.\n\nThe intent is indeed to promote it to Oslo, but that depends on the question if Ironic (or anybody else) actually wants to use a correct implementation of a hash-ring or not. I didn\u0027t get an answer to that yet, since Ironic PTL is on PTO until september. I think this can be resolved later, right?","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"99dfd8e5786bfec51df918e135bd6b6d52d64f9d","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_36b41b34","line":189,"updated":"2014-08-21 20:04:09.000000000","message":"Would it be useful to try to contact the author of https://pypi.python.org/pypi/hash_ring and be nice to other opensource projects and see if he is willing to update that for py2/py3 (it seems like it should be really easy to get that adjusted) rather then creating our own implementation...\n\nThe guy doesn\u0027t seem dead (his website @ http://amix.dk/ seems relatively recently updated) so mayb its worthwhile to ask before we recreate?","commit_id":"92b57862091a03d85074cd85d66a99d0b6f16cba"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"052566992ccc3cb263d6431d756429696cf8f87f","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_c3aa2284","line":189,"in_reply_to":"1abeadc6_2ab6628a","updated":"2014-08-22 19:32:08.000000000","message":"I think that\u0027s fair, what will happen (or I imagine happening) though is that we will lift this code out so that ironic and ceilometer (and others?) can share it, then that will go in oslo-incubator, then that will come out as a new library (or go into oslo.concurrency or something), which guess what will be pretty much the same as hash_ring on pypi, so why not just skip all that intermediary \u0027junk/process\u0027 and just use a already on pypi library in the first place. This also has the benefit of openstack helping other pypi libraries improve themselves and not fall into NIH syndrome...","commit_id":"92b57862091a03d85074cd85d66a99d0b6f16cba"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"0cab616610c95279c1c984282b41df53a5fcc36e","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_960defea","line":189,"in_reply_to":"1abeadc6_36b41b34","updated":"2014-08-21 20:09:01.000000000","message":"LOL! \"doesn\u0027t seem dead\" is the least you can really ask for. i appreciate the phrasing.\n\ni\u0027ll agree with this... and maybe add comment as to ref source for now if it takes a while.","commit_id":"92b57862091a03d85074cd85d66a99d0b6f16cba"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"ddd1a989470e775fcd26975381ab4b674cec5fdc","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    return deduped"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_2ab6628a","line":189,"in_reply_to":"1abeadc6_960defea","updated":"2014-08-22 06:21:37.000000000","message":"I would have done the py3 port myself, but the library doesn\u0027t have any SCM online.\n\nThis isn\u0027t a direct copy-paste from his lib. It\u0027s based on http://www.martinbroadhurst.com/Consistent-Hash-Ring.html, with the best implementation ideas cherry-picked from pypi:hash_lib and Ironic implementations.\n\nIt\u0027s such a small amount of code and a clean algorithm, It didn\u0027t even seem worth to me burden downstream with packaging a separate library for this, but I\u0027ll go ahead and contact the author anyway. Since that is bound to take a while, can we leave this as is and replace later if we decide so?","commit_id":"92b57862091a03d85074cd85d66a99d0b6f16cba"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d7ae67adf46fb811c0e3784bf24c52f791613424","unresolved":false,"context_lines":[{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"},{"line_number":193,"context_line":"        self._sorted_keys \u003d []"},{"line_number":194,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_d575ca98","line":191,"updated":"2014-08-28 02:22:23.000000000","message":"Sorry, is it consistent hash algorithm? may be need a test?","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"ee99a05c2854b331379c92ff7b099e57c2a95d6a","unresolved":false,"context_lines":[{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class HashRing(object):"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":192,"context_line":"        self._ring \u003d dict()"},{"line_number":193,"context_line":"        self._sorted_keys \u003d []"},{"line_number":194,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1abeadc6_0fe56bdb","line":191,"in_reply_to":"1abeadc6_d575ca98","updated":"2014-08-28 07:23:26.000000000","message":"You\u0027re right, I\u0027ll try to add some tests, even though this code is supposed to be here just temporarily, until it is either moved into oslo or replaced with a library.","commit_id":"b0d9f74d7b842b7aab61212856cb5fa410fe880c"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"83feba56f75c7329c60a48273d3443794c221b16","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"class HashRing(object):"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":191,"context_line":"        self._ring \u003d dict()"},{"line_number":192,"context_line":"        self._sorted_keys \u003d []"},{"line_number":193,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_7dc1fd4c","line":190,"updated":"2014-08-29 08:42:54.000000000","message":"Just wondering about the default value for replicas here, i.e. why 100?","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"6a91b1758f51d5c391318b6e9c099fda654c1056","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"class HashRing(object):"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    def __init__(self, nodes, replicas\u003d100):"},{"line_number":191,"context_line":"        self._ring \u003d dict()"},{"line_number":192,"context_line":"        self._sorted_keys \u003d []"},{"line_number":193,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1abeadc6_37379ee4","line":190,"in_reply_to":"1abeadc6_7dc1fd4c","updated":"2014-08-29 10:20:06.000000000","message":"hash_ring library uses about 120 (their semantics are a bit different, since they support weights). I tested this experimentally and it seemed to offer a good speed/distribution quality ratio.","commit_id":"a1669d7746cd0db5f5ef80ba857cd5f2ae2b78ff"}],"requirements.txt":[{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"585f5b5527a26403179fb0d3cdc1a928fd02dc22","unresolved":false,"context_lines":[{"line_number":33,"context_line":"SQLAlchemy\u003e\u003d0.8.4,!\u003d0.9.5,\u003c\u003d0.9.99"},{"line_number":34,"context_line":"sqlalchemy-migrate\u003e\u003d0.9.1"},{"line_number":35,"context_line":"stevedore\u003e\u003d0.14"},{"line_number":36,"context_line":"tooz\u003e\u003d0.2"},{"line_number":37,"context_line":"WebOb\u003e\u003d1.2.3"},{"line_number":38,"context_line":"WSME\u003e\u003d0.6"}],"source_content_type":"text/plain","patch_set":2,"id":"baada198_ea540c58","line":36,"updated":"2014-08-13 14:25:36.000000000","message":"please use tooz\u003e\u003d0.3","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"},{"author":{"_account_id":8052,"name":"Nejc Saje","email":"nejc@saje.info","username":"nsaje"},"change_message_id":"f6149994a14ec249c8b587e62753de8ca31b8222","unresolved":false,"context_lines":[{"line_number":33,"context_line":"SQLAlchemy\u003e\u003d0.8.4,!\u003d0.9.5,\u003c\u003d0.9.99"},{"line_number":34,"context_line":"sqlalchemy-migrate\u003e\u003d0.9.1"},{"line_number":35,"context_line":"stevedore\u003e\u003d0.14"},{"line_number":36,"context_line":"tooz\u003e\u003d0.2"},{"line_number":37,"context_line":"WebOb\u003e\u003d1.2.3"},{"line_number":38,"context_line":"WSME\u003e\u003d0.6"}],"source_content_type":"text/plain","patch_set":2,"id":"7ac7a964_ed535b6a","line":36,"in_reply_to":"baada198_ea540c58","updated":"2014-08-14 10:15:59.000000000","message":"Done","commit_id":"3be414eac4473da287288dd3c73b72f1ae255853"}],"tox.ini":[{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"aa86cbbe7a78614f0bf18b170e41306a38271115","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"[hacking]"},{"line_number":56,"context_line":"import_exceptions \u003d"},{"line_number":57,"context_line":"    ceilometer.openstack.common.gettextutils"}],"source_content_type":"text/x-properties","patch_set":7,"id":"1abeadc6_7a56bad3","line":57,"range":{"start_line":57,"start_character":15,"end_line":57,"end_character":24},"updated":"2014-08-20 09:05:10.000000000","message":"do these fox changes refer to the https://review.openstack.org/#/c/115550/ ?  Possibly this change need to inherit from it?","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"00333937ac06ed491969aad5b8fdaf0c3636f5b2","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"[hacking]"},{"line_number":56,"context_line":"import_exceptions \u003d"},{"line_number":57,"context_line":"    ceilometer.openstack.common.gettextutils"}],"source_content_type":"text/x-properties","patch_set":7,"id":"1abeadc6_3ae8c2e1","line":57,"range":{"start_line":57,"start_character":15,"end_line":57,"end_character":24},"in_reply_to":"1abeadc6_7a56bad3","updated":"2014-08-20 09:09:17.000000000","message":"after discussion in the irc it looks ok for now until 115550 will be merged","commit_id":"f5571b8f0e210717abb464254af395a07e6ce08d"}]}
