-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested autoruns on server is sending ready message before all autoruns are ready #47
Comments
Hmm. Maybe first provide a short example/test? |
Sure. The idea, in summary, is to publish all the meetings and people in those meetings (memberships), and also related data (location of the meeting, people in the meeting, roles, etc). I didn't reduce the code to avoid you thinking this could be done in a different way due to lack of details. Of course, you can find better ways to do it and I'll be glad to try 😉 export function meetingsRelatedCursors(
meetingsCursor,
{ communityId, personId: currentPersonId, accountId }
) {
const {
labelsIds: labelsIdsWithDuplicates,
meetingsIds: meetingsIdsWithDuplicates,
locationsIds: locationsIdsWithDuplicates,
} = meetingsCursor.fetch().reduce(
(acc, meeting) => ({
labelsIds: [...acc.labelsIds, ...(meeting.labelsIds || [])],
meetingsIds: [...acc.meetingsIds, meeting._id],
locationsIds: [...acc.locationsIds, meeting.locationId],
}),
{
labelsIds: [],
meetingsIds: [],
locationsIds: [],
}
);
const labelsIds = [...new Set(labelsIdsWithDuplicates)];
const meetingsIds = [...new Set(meetingsIdsWithDuplicates)];
const locationsIds = [...new Set(locationsIdsWithDuplicates)];
const locationsCursor = Locations.find({
_id: { $in: locationsIds },
});
const labelsCursor = Labels.find({ _id: { $in: labelsIds } });
const labelSetsIds = labelsCursor.map(({ labelSetId }) => labelSetId);
const labelSetsCursor = LabelSets.find({ _id: { $in: labelSetsIds } });
const defaultRolesCursor = MeetingRoles.findBy('community', {
communityId,
isDefault: false,
});
const defaultRolesIds = defaultRolesCursor.map(({ _id }) => _id);
const $or = [
currentPersonId && { personId: currentPersonId },
{ rolesIds: { $in: defaultRolesIds } },
].filter(Boolean);
this.autorun(() => {
const meetingMembershipsCursor = MeetingMemberships.find({
meetingId: { $in: meetingsIds },
$or,
});
const {
peopleIds: peopleIdsWithDuplicates,
rolesIds: rolesIdsWithDuplicates,
} = meetingMembershipsCursor.fetch().reduce(
(acc, membership) => ({
peopleIds: [...acc.peopleIds, membership.personId],
rolesIds: [...acc.rolesIds, ...(membership.rolesIds || [])],
}),
{
peopleIds: [],
rolesIds: [],
}
);
const peopleIds = [...new Set(peopleIdsWithDuplicates)];
const rolesIds = [...new Set(rolesIdsWithDuplicates)];
const peopleCursor = People.find(
{
accountId,
_id: { $in: peopleIds },
},
{ fields: { _id: 1 } }
);
const profilesCursor = PeopleProfiles.find(
{
communityId,
personId: { $in: peopleIds },
},
{
fields: {
communityId: 1,
firstName: 1,
lastName: 1,
companyName: 1,
personId: 1,
title: 1,
photoId: 1,
},
}
);
const imagesIds = profilesCursor
.map(({ photoId }) => photoId)
.filter(Boolean);
const imagesCursor = Images.find(
{
communityId,
_id: { $in: imagesIds },
},
{
fields: {
url: 1,
},
}
);
const rolesCursor = MeetingRoles.find({
_id: { $in: rolesIds },
});
return [
meetingMembershipsCursor,
peopleCursor,
profilesCursor,
imagesCursor,
rolesCursor,
];
});
return [meetingsCursor, labelsCursor, labelSetsCursor, locationsCursor];
}
Meteor.publish(
'meetings/meetings#appBySearch',
securedScope(
currentPersonScope(function appBySearch(terms) {
this.autorun(() => {
const meetingsCursor = Meetings.findBy('search', terms);
return meetingsRelatedCursors.call(this, meetingsCursor, terms);
});
})
)
); Then before the meetings are in the client my code already receives the The problem that I was solving with these nested autoruns is to avoid querying the Meetings collection very often as it does not change too much, but Memberships collection changes all the time when people interact with our app then it's important to be in a separated autorun block. Also, see that
|
Sorry. I was writing my PhD thesis so I was away for a bit. Yes, I think the problem is that code currently marks whole publish as ready when the I suggest you create a simple test case and add it to tests, which should be currently failing because of the behavior you are noticing. Keep it as simple as possible. |
Thanks, we will work on that. |
Hi, when I use nested autoruns to avoid rerunning everything on every change but with this, on the server, the ready message arrives in the client before both autorun blocks are ready and the documents are published.
If that is a bug I would be glad to help with a PR but maybe I need some directions to get started.
The text was updated successfully, but these errors were encountered: