PERF: only subscribe to a topic once for polls
in the past as views were created and destroyed poll subscriptions would change this caused a lot of load on messaging bus and uneeded traffic
This commit is contained in:
parent
bfcb0a52bb
commit
57944a0694
|
@ -15,7 +15,7 @@ export default Ember.Controller.extend({
|
||||||
showResultsDisabled: Em.computed.equal("poll.voters", 0),
|
showResultsDisabled: Em.computed.equal("poll.voters", 0),
|
||||||
hideResultsDisabled: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived"),
|
hideResultsDisabled: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived"),
|
||||||
|
|
||||||
@computed("model", "vote")
|
@computed("model", "vote", "model.voters", "model.options", "model.status")
|
||||||
poll(poll, vote) {
|
poll(poll, vote) {
|
||||||
if (poll) {
|
if (poll) {
|
||||||
const options = _.map(poll.get("options"), o => Em.Object.create(o));
|
const options = _.map(poll.get("options"), o => Em.Object.create(o));
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import PostView from "discourse/views/post";
|
import PostView from "discourse/views/post";
|
||||||
|
import TopicController from "discourse/controllers/topic";
|
||||||
|
import Post from "discourse/models/post";
|
||||||
|
|
||||||
import { on } from "ember-addons/ember-computed-decorators";
|
import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
function createPollView(container, post, poll, vote) {
|
function createPollView(container, post, poll, vote) {
|
||||||
|
@ -6,7 +9,7 @@ function createPollView(container, post, poll, vote) {
|
||||||
view = container.lookup("view:poll");
|
view = container.lookup("view:poll");
|
||||||
|
|
||||||
controller.set("vote", vote);
|
controller.set("vote", vote);
|
||||||
controller.setProperties({ model: Em.Object.create(poll), post });
|
controller.setProperties({ model: poll, post });
|
||||||
view.set("controller", controller);
|
view.set("controller", controller);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -17,13 +20,39 @@ export default {
|
||||||
|
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
|
|
||||||
const messageBus = container.lookup("message-bus:main");
|
Post.reopen({
|
||||||
|
// we need a proper ember object so it is bindable
|
||||||
|
pollsChanged: function(){
|
||||||
|
const polls = this.get("polls");
|
||||||
|
if (polls) {
|
||||||
|
this._polls = this._polls || {};
|
||||||
|
_.map(polls, (v,k) => {
|
||||||
|
const existing = this._polls[k];
|
||||||
|
if (existing) {
|
||||||
|
this._polls[k].setProperties(v);
|
||||||
|
} else {
|
||||||
|
this._polls[k] = Em.Object.create(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.set("pollsObject", this._polls);
|
||||||
|
}
|
||||||
|
}.observes("polls")
|
||||||
|
});
|
||||||
|
|
||||||
// listen for back-end to tell us when a post has a poll
|
TopicController.reopen({
|
||||||
messageBus.subscribe("/polls", data => {
|
subscribe(){
|
||||||
const post = container.lookup("controller:topic").get('model.postStream').findLoadedPost(data.post_id);
|
this._super();
|
||||||
// HACK to trigger the "postViewUpdated" event
|
this.messageBus.subscribe("/polls/" + this.get("model.id"), msg => {
|
||||||
Em.run.next(() => post.set("cooked", post.get("cooked") + " "));
|
const post = this.get('model.postStream').findLoadedPost(msg.post_id);
|
||||||
|
if (post) {
|
||||||
|
post.set('polls', msg.polls);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
unsubscribe(){
|
||||||
|
this.messageBus.unsubscribe('/polls/*');
|
||||||
|
this._super();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// overwrite polls
|
// overwrite polls
|
||||||
|
@ -32,12 +61,16 @@ export default {
|
||||||
@on("postViewInserted", "postViewUpdated")
|
@on("postViewInserted", "postViewUpdated")
|
||||||
_createPollViews($post) {
|
_createPollViews($post) {
|
||||||
const post = this.get("post"),
|
const post = this.get("post"),
|
||||||
polls = post.get("polls"),
|
|
||||||
votes = post.get("polls_votes") || {};
|
votes = post.get("polls_votes") || {};
|
||||||
|
|
||||||
|
post.pollsChanged();
|
||||||
|
const polls = post.get("pollsObject");
|
||||||
|
|
||||||
// don't even bother when there's no poll
|
// don't even bother when there's no poll
|
||||||
if (!polls) { return; }
|
if (!polls) { return; }
|
||||||
|
|
||||||
|
// TODO inject cleanly into
|
||||||
|
|
||||||
// clean-up if needed
|
// clean-up if needed
|
||||||
this._cleanUpPollViews();
|
this._cleanUpPollViews();
|
||||||
|
|
||||||
|
@ -55,23 +88,11 @@ export default {
|
||||||
pollViews[pollName] = pollView;
|
pollViews[pollName] = pollView;
|
||||||
});
|
});
|
||||||
|
|
||||||
messageBus.subscribe(`/polls/${this.get("post.id")}`, results => {
|
|
||||||
if (results && results.polls) {
|
|
||||||
_.forEach(results.polls, poll => {
|
|
||||||
if (pollViews[poll.name]) {
|
|
||||||
pollViews[poll.name].get("controller").set("model", Em.Object.create(poll));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set("pollViews", pollViews);
|
this.set("pollViews", pollViews);
|
||||||
},
|
},
|
||||||
|
|
||||||
@on("willClearRender")
|
@on("willClearRender")
|
||||||
_cleanUpPollViews() {
|
_cleanUpPollViews() {
|
||||||
messageBus.unsubscribe(`/polls/${this.get("post.id")}`);
|
|
||||||
|
|
||||||
if (this.get("pollViews")) {
|
if (this.get("pollViews")) {
|
||||||
_.forEach(this.get("pollViews"), v => v.destroy());
|
_.forEach(this.get("pollViews"), v => v.destroy());
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ after_initialize do
|
||||||
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"] ||= {}
|
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"] ||= {}
|
||||||
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"][poll_name] = options
|
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"][poll_name] = options
|
||||||
|
|
||||||
post.custom_fields[VOTES_CUSTOM_FIELD].each do |user_id, user_votes|
|
post.custom_fields[VOTES_CUSTOM_FIELD].each do |_, user_votes|
|
||||||
next unless votes = user_votes[poll_name]
|
next unless votes = user_votes[poll_name]
|
||||||
votes.each { |option| all_options[option] += 1 }
|
votes.each { |option| all_options[option] += 1 }
|
||||||
poll["voters"] += 1 if (available_options & votes.to_set).size > 0
|
poll["voters"] += 1 if (available_options & votes.to_set).size > 0
|
||||||
|
@ -92,7 +92,7 @@ after_initialize do
|
||||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||||
post.save_custom_fields(true)
|
post.save_custom_fields(true)
|
||||||
|
|
||||||
MessageBus.publish("/polls/#{post_id}", { polls: polls })
|
MessageBus.publish("/polls/#{post.topic_id}", { post_id: post_id, polls: polls })
|
||||||
|
|
||||||
return [poll, options]
|
return [poll, options]
|
||||||
end
|
end
|
||||||
|
@ -128,7 +128,7 @@ after_initialize do
|
||||||
|
|
||||||
post.save_custom_fields(true)
|
post.save_custom_fields(true)
|
||||||
|
|
||||||
MessageBus.publish("/polls/#{post_id}", { polls: polls })
|
MessageBus.publish("/polls/#{post.topic_id}", {post_id: post.id, polls: polls })
|
||||||
|
|
||||||
polls[poll_name]
|
polls[poll_name]
|
||||||
end
|
end
|
||||||
|
@ -350,7 +350,7 @@ after_initialize do
|
||||||
post.save_custom_fields(true)
|
post.save_custom_fields(true)
|
||||||
|
|
||||||
# publish the changes
|
# publish the changes
|
||||||
MessageBus.publish("/polls/#{post.id}", { polls: polls })
|
MessageBus.publish("/polls/#{post.topic_id}", { post_id: post.id, polls: polls })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -370,7 +370,9 @@ after_initialize do
|
||||||
# tells the front-end we have a poll for that post
|
# tells the front-end we have a poll for that post
|
||||||
on(:post_created) do |post|
|
on(:post_created) do |post|
|
||||||
next if post.is_first_post? || post.custom_fields[POLLS_CUSTOM_FIELD].blank?
|
next if post.is_first_post? || post.custom_fields[POLLS_CUSTOM_FIELD].blank?
|
||||||
MessageBus.publish("/polls", { post_id: post.id })
|
MessageBus.publish("/polls/#{post.topic_id}", {
|
||||||
|
post_id: post.id,
|
||||||
|
polls: post.custom_fields[POLLS_CUSTOM_FIELD]})
|
||||||
end
|
end
|
||||||
|
|
||||||
add_to_serializer(:post, :polls, false) { post_custom_fields[POLLS_CUSTOM_FIELD] }
|
add_to_serializer(:post, :polls, false) { post_custom_fields[POLLS_CUSTOM_FIELD] }
|
||||||
|
|
Loading…
Reference in New Issue