#format rst ============================== Merge proposal's diffs updates ============================== Overview ======== This feature takes advantage of the LongPoll_ machinery to update merge proposal's diffs as soon as a new version becomes available (no more page reloads required!). On the backend side, a ILongPollEvent is fired each time a new version of the diff is available. A small piece of Javascript code is hooked up to the counterpart Javascript event fired by the LongPoll machinery to update the diff content via a simple XHR request. .. _LongPoll: LongPoll This is the first real-world of the LongPoll machinery so we go into the details of what should be done hoping that this would be used as a reference point for those interested in using it. Feature Flag ============ This feature is behind a feature flag *longpoll.merge_proposals.enabled* and can be enabled by adding this line to +feature-rules:: longpoll.merge_proposals.enabled default 1 on Backend side ============ Event wiring ------------ In this case, the event is triggered by the zope event bridge which adapts any Zope event to ILongPollEvent. The event itself is fired when the ObjectModifiedEvent is notified:: merge_proposal_event = ObjectModifiedEvent( merge_proposal, merge_proposal_snapshot, vars(merge_proposal_delta).keys()) notify(merge_proposal_event) Request subscription -------------------- Then, the request is subscribed_ to the merge proposal object (that is now adapted to ILongPollEvent):: from lp.app.longpoll import subscribe class BranchMergeProposalView(...) def initialize(self): event_key = subscribe(self.context).event_key cache.objects['merge_proposal_event_key'] = event_key .. _subscribed: http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/view/head:/lib/lp/code/browser/branchmergeproposal.py Note that the JSONRequestCache is populated with the name of the event that the Javascript side will listen to. Javascript side =============== All the code to `update the merge proposal diff`_ is independent of the LongPoll code. All it has to do is be fired when the "Merge proposal updated" event is triggered_:: if (Y.Lang.isValue(LP.cache.merge_proposal_event_key)) { var updater = new Y.lp.code.branchmergeproposal.updater.UpdaterWidget( {srcNode: Y.one('#diff-area')}); Y.on(LP.cache.merge_proposal_event_key, function(data) { if (Y.lp.code.branchmergeproposal.updater.is_mp_diff_updated(data)) { updater.update(); } }); } .. _`update the merge proposal diff`: http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/view/head:/lib/lp/code/javascript/branchmergeproposal.updater.js .. _triggered: http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/view/head:/lib/lp/code/templates/branchmergeproposal-index.pt