README is still a WIP.
Live algorithm for assigning students to groups.
This library provides a set of tools to consistently assign students to groups as they enter events, across multiple events, courses, and with the algorithm running on multiple servers, in a distributed manner.
Using the Live Grouper is simple, start by initializing, then create an event, and start assigning students:
// Import from grouper library
import {
initGrouper,
createEvent,
getGroupAssignment,
// Types
GrouperAlgorithm,
} from 'dce-live-grouper';
// Import a Collection constructor
import { Collection } from 'dce-mango';
// Initialize the internal state and connection to the database
initGrouper(Collection);
// Create an event
await createEvent({
courseId: 1,
eventId: 'awesome-event',
// Here we are choosing to have any number of groups with a max size of 5
grouperAlgorithm: GrouperAlgorithm.FixedGroupSize,
capacity: 5,
});
// Assign a student to a group
const studentAssignment = await getGroupAssignment({
courseId: 1,
eventId: 'awesome-event',
studentId: 1,
});
It's possible to run with any number of courses, events, or students, and the internal algorithms will guarantee data consistency. The main thing to keep in mind is that you will need to retry requests if they fail.
More in-depth:
There are two choices of GrouperAlgorithm
:
-
FixedGroupSize
- where we specify a max size for the groups, but can have any number of groups. -
FixedNumGroups
- where we specify a max number of groups, but groups can be of any size.
For FixedGroupSize
we need to specify a capacity
when we create an event:
await createEvent({
eventId: 'my-event',
courseId: 1,
grouperAlgorithm: GrouperAlgorithm.FixedGroupSize,
// This is the max size for any one group
capacity: 5,
});
For FixedNumGroups
we need to specify a maxGroups
await createEvent({
eventId: 'my-event',
courseId: 1,
grouperAlgorithm: GrouperAlgorithm.FixedNumGroups,
// This is the max number of groups
maxGroups: 5,
});
If you want direct access to the events and courses, simply use the event and course collections returned by initGrouper
:
const {
eventCollection,
courseCollection,
} = initGrouper(Collection);
// Now we can manually interact with the collections:
const myEvents = await eventCollection.find({ id: '1-my-event' });
const myEvent = myEvents[0];
// Manually changing the max number of groups or the group size:
if (myEvent.maxGroups) {
await eventCollection.insert({
...myEvent,
maxGroups: myEvent.maxGroups + 1,
});
} else {
await eventCollection.insert({
...myEvent,
capacity: myEvent.capacity + 2,
});
}
// And even delete events or courses
await eventCollection.delete({ id: '1-my-event' });
await courseCollection.delete({ id: 1 });
To assigned banned pairs, use the get and set functions:
// Imports
import { initGrouper, getBannedPairs, setBannedPairs } from 'dce-live-grouper';
import { Collection } from 'dce-mango';
initGrouper(Collection);
// Choosing a course
const courseId = 5;
// Getting
const bannedPairs = await getBannedPairs(courseId);
// Change the banned pairs
bannedPairs.push({
student1: 333,
student2: 666,
});
// Push the changes to the course in the database
await setBannedPairs({
courseId,
bannedPairs,
});
// Completely resetting a courses banned pairs:
await setBannedPairs({
courseId: 7,
bannedPairs: [],
});
Pre-assignments allow you to assign students to groups before they arrive:
import { createEvent, PreAssignment } from 'dce-live-grouper';
// For example, we want student 1 and student 2 to sit together in group 1
const preAssignments = [
{
studentId: 1,
groupNum: 1,
},
{
studentId: 2,
groupNum: 1,
},
];
await createEvent({
...eventOpts, // The other configuration options for the event
preAssignments,
});
// Now, if I try to assign student 1, it will return group 1
const { groupNum } = await getGroupAssignment({ ...eventOpts, studentId: 1 });
if (groupNum == 1) {
console.log('Pre-assignment worked!');
} else {
console.log('This should not happen...');
}
To run the unit tests, you will need to set a MONGO_URL
in a .env
file, following along with the .env.template
. Then, simply run npm run test
in the root of the repository.
For more detailed tests of the algorithm suite, see the dce-live-grouper-tests-and-training repository.
There are two key parts of this library:
- the core algorithms for choosing groups for students as they join an event
- the capability for these algorithms to run on multiple servers in a distributed manner
For the first part, see the ALGORITHMS.md
file in src/algorithms
. There we describe the different algorithm choices, how they are designed, and other details.
For the second part, we implemented a 'batch-queue', which is described in detail in BATCH_QUEUE.md
in the src/queue
directory.