)]}'
{"karbor/db/sqlalchemy/api.py":[{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"a78c8e72f1220c2ffab2c82ddeaee4f1a560d632","unresolved":false,"context_lines":[{"line_number":508,"context_line":"        filters[\u0027trigger_id\u0027] \u003d trigger_id"},{"line_number":509,"context_line":""},{"line_number":510,"context_line":"    session \u003d get_session()"},{"line_number":511,"context_line":"    deleted \u003d None"},{"line_number":512,"context_line":"    try:"},{"line_number":513,"context_line":"        with session.begin():"},{"line_number":514,"context_line":"            deleted \u003d model_query("}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_3c27b715","line":511,"range":{"start_line":511,"start_character":4,"end_line":511,"end_character":18},"updated":"2017-10-11 01:00:25.000000000","message":"this variable can be removed","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"a78c8e72f1220c2ffab2c82ddeaee4f1a560d632","unresolved":false,"context_lines":[{"line_number":528,"context_line":"def trigger_execution_get_next(context):"},{"line_number":529,"context_line":"    session \u003d get_session()"},{"line_number":530,"context_line":"    try:"},{"line_number":531,"context_line":"        with session.begin():"},{"line_number":532,"context_line":"            query \u003d _generate_paginate_query("},{"line_number":533,"context_line":"                context, session,"},{"line_number":534,"context_line":"                marker\u003dNone,"},{"line_number":535,"context_line":"                limit\u003d1,"},{"line_number":536,"context_line":"                sort_keys\u003d(\u0027execution_time\u0027, ),"},{"line_number":537,"context_line":"                sort_dirs\u003d(\u0027desc\u0027, ),"},{"line_number":538,"context_line":"                filters\u003dNone,"},{"line_number":539,"context_line":"                paginate_type\u003dmodels.TriggerExecution,"},{"line_number":540,"context_line":"            )"},{"line_number":541,"context_line":"            result \u003d query.first()"},{"line_number":542,"context_line":"    except Exception as e:"},{"line_number":543,"context_line":"        LOG.warning(\"Unable to get next trigger execution %s\", e)"},{"line_number":544,"context_line":"        return None"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_bc61673c","line":541,"range":{"start_line":531,"start_character":8,"end_line":541,"end_character":34},"updated":"2017-10-11 01:00:25.000000000","message":"IMO, we should add a read lock here, \u0027get\u0027 and \u0027update\u0027 should be in one transaction.\n(or add lock in time_trigger.py)\nOtherwise, maybe the multi node will get same trigger execution concurrently.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"5fb00d34911bcb8ed5f919ceef470153996fbee9","unresolved":false,"context_lines":[{"line_number":528,"context_line":"def trigger_execution_get_next(context):"},{"line_number":529,"context_line":"    session \u003d get_session()"},{"line_number":530,"context_line":"    try:"},{"line_number":531,"context_line":"        with session.begin():"},{"line_number":532,"context_line":"            query \u003d _generate_paginate_query("},{"line_number":533,"context_line":"                context, session,"},{"line_number":534,"context_line":"                marker\u003dNone,"},{"line_number":535,"context_line":"                limit\u003d1,"},{"line_number":536,"context_line":"                sort_keys\u003d(\u0027execution_time\u0027, ),"},{"line_number":537,"context_line":"                sort_dirs\u003d(\u0027desc\u0027, ),"},{"line_number":538,"context_line":"                filters\u003dNone,"},{"line_number":539,"context_line":"                paginate_type\u003dmodels.TriggerExecution,"},{"line_number":540,"context_line":"            )"},{"line_number":541,"context_line":"            result \u003d query.first()"},{"line_number":542,"context_line":"    except Exception as e:"},{"line_number":543,"context_line":"        LOG.warning(\"Unable to get next trigger execution %s\", e)"},{"line_number":544,"context_line":"        return None"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_40c14654","line":541,"range":{"start_line":531,"start_character":8,"end_line":541,"end_character":34},"in_reply_to":"5f4e5783_bc61673c","updated":"2017-10-11 08:24:36.000000000","message":"That\u0027s ok if multiple nodes get that trigger.\nThese nodes compute the next execution time and then use \u0027trigger_execution_update\u0027 (from above) which resembles an atomic \u0027compare and set\u0027. Only one node will succeed doing so, and it will be the one handling that event.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"}],"karbor/db/sqlalchemy/migrate_repo/versions/001_karbor_init.py":[{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"d8ab780d3d7180ceaf7b2d8519650f958b8d18cf","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":122,"context_line":"    )"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    trigger_executions \u003d Table("},{"line_number":125,"context_line":"        \u0027trigger_executions\u0027, meta,"},{"line_number":126,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":127,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":128,"context_line":"        Column(\u0027deleted_at\u0027, DateTime),"},{"line_number":129,"context_line":"        Column(\u0027deleted\u0027, Boolean, nullable\u003dFalse),"},{"line_number":130,"context_line":"        Column(\u0027id\u0027, String(length\u003d36), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":131,"context_line":"        Column(\u0027trigger_id\u0027, String(length\u003d36), unique\u003dTrue, nullable\u003dFalse,"},{"line_number":132,"context_line":"               index\u003dTrue),"},{"line_number":133,"context_line":"        Column(\u0027execution_time\u0027, DateTime, nullable\u003dFalse, index\u003dTrue),"},{"line_number":134,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":135,"context_line":"    )"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    scheduled_operations \u003d Table("},{"line_number":138,"context_line":"        \u0027scheduled_operations\u0027, meta,"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_7062b040","line":135,"range":{"start_line":124,"start_character":4,"end_line":135,"end_character":5},"updated":"2017-10-12 09:10:24.000000000","message":"maybe we should add \u0027node\u0027 column id in \u0027trigger_executions\u0027.\nIn my test, I created three scheduled operations (s1, s2, s3) with three plan and use the same trigger.\ns1 and s3 are scheduled to operationengine in node1, s2 is scheduled to operationengine in node2. the task in node2 has never been executed. It is because the trigger start time of the tasks in node1(s1, s3) are not completely same with the task in node2(s2).","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"87850b2bfc651e3f6900cdf6bae194f5c41335af","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":122,"context_line":"    )"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    trigger_executions \u003d Table("},{"line_number":125,"context_line":"        \u0027trigger_executions\u0027, meta,"},{"line_number":126,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":127,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":128,"context_line":"        Column(\u0027deleted_at\u0027, DateTime),"},{"line_number":129,"context_line":"        Column(\u0027deleted\u0027, Boolean, nullable\u003dFalse),"},{"line_number":130,"context_line":"        Column(\u0027id\u0027, String(length\u003d36), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":131,"context_line":"        Column(\u0027trigger_id\u0027, String(length\u003d36), unique\u003dTrue, nullable\u003dFalse,"},{"line_number":132,"context_line":"               index\u003dTrue),"},{"line_number":133,"context_line":"        Column(\u0027execution_time\u0027, DateTime, nullable\u003dFalse, index\u003dTrue),"},{"line_number":134,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":135,"context_line":"    )"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    scheduled_operations \u003d Table("},{"line_number":138,"context_line":"        \u0027scheduled_operations\u0027, meta,"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_67dd5341","line":135,"range":{"start_line":124,"start_character":4,"end_line":135,"end_character":5},"in_reply_to":"5f4e5783_07aa1fd1","updated":"2017-10-12 09:56:34.000000000","message":"Another patch is required to make sure that scheduled operations are registered to all nodes, and that nodes register scheduled operations when they are starting.\n---- hi, Yuval. The scheduled operation cannot be registered to all nodes. One scheduled operation only can be triggered in one node. If it will be registered to all nodes. That means that this  scheduled operation will be executed repeatedly in every nodes.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"22273acb46f9c9949087841a221f93aac2c9108f","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":122,"context_line":"    )"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    trigger_executions \u003d Table("},{"line_number":125,"context_line":"        \u0027trigger_executions\u0027, meta,"},{"line_number":126,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":127,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":128,"context_line":"        Column(\u0027deleted_at\u0027, DateTime),"},{"line_number":129,"context_line":"        Column(\u0027deleted\u0027, Boolean, nullable\u003dFalse),"},{"line_number":130,"context_line":"        Column(\u0027id\u0027, String(length\u003d36), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":131,"context_line":"        Column(\u0027trigger_id\u0027, String(length\u003d36), unique\u003dTrue, nullable\u003dFalse,"},{"line_number":132,"context_line":"               index\u003dTrue),"},{"line_number":133,"context_line":"        Column(\u0027execution_time\u0027, DateTime, nullable\u003dFalse, index\u003dTrue),"},{"line_number":134,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":135,"context_line":"    )"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    scheduled_operations \u003d Table("},{"line_number":138,"context_line":"        \u0027scheduled_operations\u0027, meta,"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_7ad60a2a","line":135,"range":{"start_line":124,"start_character":4,"end_line":135,"end_character":5},"in_reply_to":"5f4e5783_67dd5341","updated":"2017-10-12 10:36:00.000000000","message":"registered to multiple nodes !\u003d triggered on all nodes\n\nThis patch purpose is to make sure that a trigger is triggered only on one node, calling the scheduled operations registered to it.\nThe scheduled operations must be available to all nodes. Consider a multi node operationengine - if one node crashes, if a node crashes, all other nodes must see that scheduled operation in order to call it.\nAnother option, which is better in my opinion, is to not keep the registered scheduled operations in memory, only in database. Once a trigger is triggered, just look in the database for the scheduled operations registered to it.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"fdfa39741180e49adb5f39c1ed95ed44c25a1dd7","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":122,"context_line":"    )"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    trigger_executions \u003d Table("},{"line_number":125,"context_line":"        \u0027trigger_executions\u0027, meta,"},{"line_number":126,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":127,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":128,"context_line":"        Column(\u0027deleted_at\u0027, DateTime),"},{"line_number":129,"context_line":"        Column(\u0027deleted\u0027, Boolean, nullable\u003dFalse),"},{"line_number":130,"context_line":"        Column(\u0027id\u0027, String(length\u003d36), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":131,"context_line":"        Column(\u0027trigger_id\u0027, String(length\u003d36), unique\u003dTrue, nullable\u003dFalse,"},{"line_number":132,"context_line":"               index\u003dTrue),"},{"line_number":133,"context_line":"        Column(\u0027execution_time\u0027, DateTime, nullable\u003dFalse, index\u003dTrue),"},{"line_number":134,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":135,"context_line":"    )"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    scheduled_operations \u003d Table("},{"line_number":138,"context_line":"        \u0027scheduled_operations\u0027, meta,"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_07aa1fd1","line":135,"range":{"start_line":124,"start_character":4,"end_line":135,"end_character":5},"in_reply_to":"5f4e5783_7062b040","updated":"2017-10-12 09:46:20.000000000","message":"Sorry if that was not clear enough. This patch handles the multi node handling of triggers only, not scheduled operations.\nCurrently, in operationengine/rpcapi.py - scheduled operations are registered using rpc \u0027call\u0027 and not \u0027cast\u0027.\nAnother patch is required to make sure that scheduled operations are registered to all nodes, and that nodes register scheduled operations when they are starting.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"ab71fcb5738c906fb64a91b7ea7749e9c2377f0f","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":122,"context_line":"    )"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    trigger_executions \u003d Table("},{"line_number":125,"context_line":"        \u0027trigger_executions\u0027, meta,"},{"line_number":126,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":127,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":128,"context_line":"        Column(\u0027deleted_at\u0027, DateTime),"},{"line_number":129,"context_line":"        Column(\u0027deleted\u0027, Boolean, nullable\u003dFalse),"},{"line_number":130,"context_line":"        Column(\u0027id\u0027, String(length\u003d36), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":131,"context_line":"        Column(\u0027trigger_id\u0027, String(length\u003d36), unique\u003dTrue, nullable\u003dFalse,"},{"line_number":132,"context_line":"               index\u003dTrue),"},{"line_number":133,"context_line":"        Column(\u0027execution_time\u0027, DateTime, nullable\u003dFalse, index\u003dTrue),"},{"line_number":134,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027"},{"line_number":135,"context_line":"    )"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    scheduled_operations \u003d Table("},{"line_number":138,"context_line":"        \u0027scheduled_operations\u0027, meta,"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_1adb96ed","line":135,"range":{"start_line":124,"start_character":4,"end_line":135,"end_character":5},"in_reply_to":"5f4e5783_7ad60a2a","updated":"2017-10-12 10:49:23.000000000","message":"I understand. Agree with yuval.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"}],"karbor/services/operationengine/engine/triggers/timetrigger/time_trigger.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"8f72898afdbe3d4c0dbf4fff216f144c3f3241eb","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    _triggers \u003d {}"},{"line_number":65,"context_line":"    _scheduling_grace \u003d timedelta(seconds\u003dCONF.trigger_scheduling_grace)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def __init__(self, trigger_id, trigger_property, executor):"},{"line_number":68,"context_line":"        super(TimeTrigger, self).__init__("},{"line_number":69,"context_line":"            trigger_id, trigger_property, executor)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_5c7c5eb4","line":67,"range":{"start_line":67,"start_character":8,"end_line":67,"end_character":16},"updated":"2017-07-26 02:08:22.000000000","message":"hi yuval, Does it mean that every operation engine service in multi nodes will init a LoopingCall about TimeTrigger?\nDo we need consider this situation? Although every operation engine service start a LoopingCall about TimeTrigger, the rpc message about creating a scheduled_operation only be handled by one node. So the execution about operation only occurs in one node?","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"a11f72c8c323289c39d55164f874f783e11ae8d7","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    _triggers \u003d {}"},{"line_number":65,"context_line":"    _scheduling_grace \u003d timedelta(seconds\u003dCONF.trigger_scheduling_grace)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def __init__(self, trigger_id, trigger_property, executor):"},{"line_number":68,"context_line":"        super(TimeTrigger, self).__init__("},{"line_number":69,"context_line":"            trigger_id, trigger_property, executor)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_fcc2d958","line":67,"range":{"start_line":67,"start_character":8,"end_line":67,"end_character":16},"in_reply_to":"ff346bd7_31fd2ab1","updated":"2017-07-26 15:59:42.000000000","message":"Yes, and using database transactions, we ensure that the operation will be called only once.","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"68c5c671006a69350e463a49921dca924bfb7726","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    _triggers \u003d {}"},{"line_number":65,"context_line":"    _scheduling_grace \u003d timedelta(seconds\u003dCONF.trigger_scheduling_grace)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def __init__(self, trigger_id, trigger_property, executor):"},{"line_number":68,"context_line":"        super(TimeTrigger, self).__init__("},{"line_number":69,"context_line":"            trigger_id, trigger_property, executor)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_fad66f27","line":67,"range":{"start_line":67,"start_character":8,"end_line":67,"end_character":16},"in_reply_to":"ff346bd7_5c7c5eb4","updated":"2017-07-26 06:09:31.000000000","message":"The loopingcall is class variable, will only be instantiated once, see comment below.","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"5aaff74f2219682214ea213c91f952437b794cd6","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    _triggers \u003d {}"},{"line_number":65,"context_line":"    _scheduling_grace \u003d timedelta(seconds\u003dCONF.trigger_scheduling_grace)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def __init__(self, trigger_id, trigger_property, executor):"},{"line_number":68,"context_line":"        super(TimeTrigger, self).__init__("},{"line_number":69,"context_line":"            trigger_id, trigger_property, executor)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_31fd2ab1","line":67,"range":{"start_line":67,"start_character":8,"end_line":67,"end_character":16},"in_reply_to":"ff346bd7_fad66f27","updated":"2017-07-26 15:35:08.000000000","message":"I know that in one node, the loopingcall is class variable, will only be instantiated once.\nI mean that the karbor operationengine services are installed in several different nodes (VMs or physical machines). The LoopingCall of operationengine\u0027s TimeTrigger class will be inited in every nodes?","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"68c5c671006a69350e463a49921dca924bfb7726","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        self._trigger_execution_new(self._id, first_run_time)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"        if not self.__class__._loopingcall:"},{"line_number":81,"context_line":"            self.__class__._loopingcall \u003d loopingcall.FixedIntervalLoopingCall("},{"line_number":82,"context_line":"                self._loop)"},{"line_number":83,"context_line":"            self.__class__._loopingcall.start("},{"line_number":84,"context_line":"                interval\u003dCONF.trigger_poll_interval,"},{"line_number":85,"context_line":"                stop_on_exception\u003dFalse,"},{"line_number":86,"context_line":"            )"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        self._register()"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_bae0e7fb","line":86,"range":{"start_line":80,"start_character":0,"end_line":86,"end_character":13},"updated":"2017-07-26 06:09:31.000000000","message":"here the looping call will be instantiated, only once","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"78bf4b12cc5c2106860e2bc54d3cc37aca83b747","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                trigger_property[\u0027end_time\u0027],"},{"line_number":120,"context_line":"                timer,"},{"line_number":121,"context_line":"            )"},{"line_number":122,"context_line":"            res \u003d False"},{"line_number":123,"context_line":"            if not next_exec_time:"},{"line_number":124,"context_line":"                LOG.info(\"No more planned executions for trigger\")"},{"line_number":125,"context_line":"                res \u003d cls._trigger_execution_delete("}],"source_content_type":"text/x-python","patch_set":18,"id":"df3967d1_be7a7285","line":122,"range":{"start_line":122,"start_character":12,"end_line":122,"end_character":23},"updated":"2017-07-31 00:54:33.000000000","message":"this can be removed","commit_id":"7f98d3443cb06e12cd0eb88ba2b58cf611c59f81"},{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"d8ab780d3d7180ceaf7b2d8519650f958b8d18cf","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    def _loop(cls):"},{"line_number":94,"context_line":"        while True:"},{"line_number":95,"context_line":"            now \u003d datetime.utcnow()"},{"line_number":96,"context_line":"            exec_to_handle \u003d cls._trigger_execution_get_next()"},{"line_number":97,"context_line":"            if not exec_to_handle:"},{"line_number":98,"context_line":"                LOG.debug(\"No next trigger executions\")"},{"line_number":99,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_b0f028cb","line":96,"range":{"start_line":96,"start_character":12,"end_line":96,"end_character":62},"updated":"2017-10-12 09:10:24.000000000","message":"IMO, we should get all the latest trigger executions with different trigger id, so that all the trigger executions can be executed.\n\nIn my test, I create two triggers t1 and t2, so there are two records in table \u0027trigger_executions\u0027. But only the latest will be updated.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"86e84ae16e91de73123114cf529cecc8b6b70d54","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    def _loop(cls):"},{"line_number":94,"context_line":"        while True:"},{"line_number":95,"context_line":"            now \u003d datetime.utcnow()"},{"line_number":96,"context_line":"            exec_to_handle \u003d cls._trigger_execution_get_next()"},{"line_number":97,"context_line":"            if not exec_to_handle:"},{"line_number":98,"context_line":"                LOG.debug(\"No next trigger executions\")"},{"line_number":99,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_3d5acc29","line":96,"range":{"start_line":96,"start_character":12,"end_line":96,"end_character":62},"in_reply_to":"5f4e5783_5a834ecd","updated":"2017-10-12 10:58:07.000000000","message":"I\u0027m not in front a computer where I can test.\nProbably an issue in karbor/db/sqlalchemy/api.py line 537. Should be \u0027asc\u0027 and not \u0027desc\u0027, I\u0027ll change that later.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":21224,"name":"jiaopengju","email":"jiaopengju_yewu@cmss.chinamobile.com","username":"jiaopengju"},"change_message_id":"ab71fcb5738c906fb64a91b7ea7749e9c2377f0f","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    def _loop(cls):"},{"line_number":94,"context_line":"        while True:"},{"line_number":95,"context_line":"            now \u003d datetime.utcnow()"},{"line_number":96,"context_line":"            exec_to_handle \u003d cls._trigger_execution_get_next()"},{"line_number":97,"context_line":"            if not exec_to_handle:"},{"line_number":98,"context_line":"                LOG.debug(\"No next trigger executions\")"},{"line_number":99,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_5a834ecd","line":96,"range":{"start_line":96,"start_character":12,"end_line":96,"end_character":62},"in_reply_to":"5f4e5783_a463491a","updated":"2017-10-12 10:49:23.000000000","message":"this is the records in my environment.\n\nhttps://paste.ubuntu.com/25725528/\n\nI have two nodes of operationengine, you can see that only the latest created one being updated.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"},{"author":{"_account_id":20883,"name":"Yuval Brik","email":"yuval@brik.org.il","username":"yuvalbr"},"change_message_id":"fdfa39741180e49adb5f39c1ed95ed44c25a1dd7","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    def _loop(cls):"},{"line_number":94,"context_line":"        while True:"},{"line_number":95,"context_line":"            now \u003d datetime.utcnow()"},{"line_number":96,"context_line":"            exec_to_handle \u003d cls._trigger_execution_get_next()"},{"line_number":97,"context_line":"            if not exec_to_handle:"},{"line_number":98,"context_line":"                LOG.debug(\"No next trigger executions\")"},{"line_number":99,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":32,"id":"5f4e5783_a463491a","line":96,"range":{"start_line":96,"start_character":12,"end_line":96,"end_character":62},"in_reply_to":"5f4e5783_b0f028cb","updated":"2017-10-12 09:46:20.000000000","message":"It is ok if there are more than one trigger execution which should be executed. Note that this is all in a \"while True\" loop. It handles one trigger at a time - fetching more than one trigger at a time means that until we handle the second trigger execution, someone might have picked up that trigger execution somewhere else.","commit_id":"eceb7fc82b27b941838c1c2438f93c95214d140d"}],"karbor/services/operationengine/rpcapi.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"b0262e682828d36e5a636658d254452653dee37f","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                                 trigger_id\u003dtrigger_id)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_trigger(self, ctxt, trigger):"},{"line_number":67,"context_line":"        return self._client.cast(ctxt, \u0027create_trigger\u0027, trigger\u003dtrigger)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def delete_trigger(self, ctxt, trigger_id):"},{"line_number":70,"context_line":"        return self._client.cast(ctxt, \u0027delete_trigger\u0027, trigger_id\u003dtrigger_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bf57530f_c0d1d459","line":67,"range":{"start_line":67,"start_character":0,"end_line":67,"end_character":73},"updated":"2017-09-20 12:46:32.000000000","message":"hi yuval, The fanout property should be True. The cast() method is used to invoke an RPC method that does not return a value[1]. You can see here[2]. \n\n\n\n[1]https://docs.openstack.org/oslo.messaging/latest/reference/rpcclient.html\n[2]https://github.com/openstack/nova/blob/5c322924fad286fede3435c42d77e8cc14d846b0/nova/scheduler/rpcapi.py#L142","commit_id":"864a60f27c5403f7760693921a2e85b9bc801e8e"},{"author":{"_account_id":22056,"name":"yushangbin","email":"shangbin.yu@easystack.cn","username":"yushangbin"},"change_message_id":"e18ef6bdd707a16b88e1b0ff0da1c2a765cde9c8","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                                 trigger_id\u003dtrigger_id)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_trigger(self, ctxt, trigger):"},{"line_number":67,"context_line":"        return self._client.cast(ctxt, \u0027create_trigger\u0027, trigger\u003dtrigger)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def delete_trigger(self, ctxt, trigger_id):"},{"line_number":70,"context_line":"        return self._client.cast(ctxt, \u0027delete_trigger\u0027, trigger_id\u003dtrigger_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"7f515b1d_01172ea6","line":67,"range":{"start_line":67,"start_character":0,"end_line":67,"end_character":73},"in_reply_to":"bf57530f_c0d1d459","updated":"2017-09-30 02:18:36.000000000","message":"hi chenying, the essential difference between cast and call is if waiting for a return, I don\u0027t think create trigger needs waiting for a return, so cast is OK.","commit_id":"864a60f27c5403f7760693921a2e85b9bc801e8e"}],"karbor/tests/fullstack/test_triggers.py":[{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"8f72898afdbe3d4c0dbf4fff216f144c3f3241eb","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        self.assertEqual(trigger_name, trigger.name)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def test_triggers_update(self):"},{"line_number":45,"context_line":"        trigger_name \u003d \"FullStack Trigger Test Get\""},{"line_number":46,"context_line":"        pattern \u003d \"BEGIN:VEVENT\\nRRULE:FREQ\u003dWEEKLY;INTERVAL\u003d1;\\nEND:VEVENT\""},{"line_number":47,"context_line":"        trigger \u003d self.store(objects.Trigger())"},{"line_number":48,"context_line":"        trigger.create(\u0027time\u0027, {\u0027pattern\u0027: pattern, \u0027format\u0027: \u0027calendar\u0027},"}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_dcedee8b","line":45,"range":{"start_line":45,"start_character":47,"end_line":45,"end_character":50},"updated":"2017-07-26 02:08:22.000000000","message":"S/Get/Update","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"},{"author":{"_account_id":17151,"name":"chenying","email":"chenyingko@gmail.com","username":"chenying"},"change_message_id":"8f72898afdbe3d4c0dbf4fff216f144c3f3241eb","unresolved":false,"context_lines":[{"line_number":55,"context_line":"            }"},{"line_number":56,"context_line":"        }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"        self.karbor_client.triggers.update("},{"line_number":59,"context_line":"            trigger.id,"},{"line_number":60,"context_line":"            properties,"},{"line_number":61,"context_line":"        )"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def test_triggers_delete(self):"},{"line_number":64,"context_line":"        pattern \u003d \"BEGIN:VEVENT\\nRRULE:FREQ\u003dWEEKLY;INTERVAL\u003d1;\\nEND:VEVENT\""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff346bd7_bc77cad4","line":61,"range":{"start_line":58,"start_character":0,"end_line":61,"end_character":9},"updated":"2017-07-26 02:08:22.000000000","message":"Do we need add a assert about this test here?","commit_id":"e20384072df03b72951f082049a6f7dd8ebefff6"}]}
