Skip to content

Commit

Permalink
Update schedules on line item save
Browse files Browse the repository at this point in the history
  • Loading branch information
zarathustra323 committed Jan 17, 2019
1 parent e1e7d1a commit 77aa695
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 44 deletions.
1 change: 1 addition & 0 deletions services/graphql/src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = cleanEnv(process.env, {
AWS_ACCESS_KEY_ID: nonemptystr({ desc: 'The AWS access key value.' }),
AWS_SECRET_ACCESS_KEY: nonemptystr({ desc: 'The AWS secret access key value.' }),
S3_BUCKET: nonemptystr({ desc: 'The S3 bucket for uploading images.', default: 'cdn.email-x.io' }),
CDN_HOST: nonemptystr({ desc: 'The CDN hostname for serving ad images.', default: 'cdn.email-x.io' }),
MONGO_DSN: nonemptystr({ desc: 'The MongoDB DSN to connect to.' }),
REDIS_DSN: nonemptystr({ desc: 'The Redis DSN to connect to.' }),
INTERNAL_PORT: port({ desc: 'The internal port that express will run on.', default: 80 }),
Expand Down
4 changes: 2 additions & 2 deletions services/graphql/src/mongoose/schema/correlator.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { Schema } = require('mongoose');

const schema = new Schema({
correlator: String,
value: String,
src: String,
url: String,
adId: Schema.Types.ObjectId,
});

schema.index({ correlator: 1 });
schema.index({ value: 1 }, { unique: true });

module.exports = schema;
5 changes: 5 additions & 0 deletions services/graphql/src/mongoose/schema/image.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { Schema } = require('mongoose');
const { CDN_HOST } = require('../../env');

const schema = new Schema({
filename: {
Expand Down Expand Up @@ -36,4 +37,8 @@ const schema = new Schema({
},
});

schema.virtual('serveSrc').get(function getServeSrc() {
return `https://${CDN_HOST}/${this.get('s3.key')}`;
});

module.exports = schema;
97 changes: 59 additions & 38 deletions services/graphql/src/mongoose/schema/lineitem.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,6 @@ schema.method('getRequirements', async function getRequirements() {
return needs.sort().join(', ');
});

schema.post('init', function setInitialStatus() {
this.$initialStatus = this.status;
this.$initialDates = this.dates;
});

// @todo If the order name changes, this will also have to change.
schema.pre('validate', async function setOrderAndAdvertiser() {
if (this.isModified('orderId') || !this.orderName || !this.advertiserName || !this.advertiserId) {
Expand All @@ -212,44 +207,70 @@ schema.pre('save', async function setReady() {
}
});

const createSchedules = () => {
schema.post('save', async function updateSchedules() {
const lineitem = this;
const bulkOps = [
{ deleteMany: { filter: { lineitemId: lineitem._id } } },
];

};
const { targeting, priority, dates } = lineitem;
const { adunitIds, deploymentIds, publisherIds } = targeting || {};

const handleSchedules = async (lineitem, create = false) => {
try {
await connection.model('schedule').remove({ lineitemId: lineitem.id });
if (create) {
await createSchedules(lineitem);
}
} catch (e) {
// @todo Log to newrelic or whatever.
throw e;
}
};
const ids = {
adunit: isArray(adunitIds) ? adunitIds : [],
deployment: isArray(deploymentIds) ? deploymentIds : [],
publisher: isArray(publisherIds) ? publisherIds : [],
};

schema.post('save', async function updateSchedules() {
const hasStatusChanged = this.$initialStatus !== this.status;
const { $initialDates, dates } = this;
const ads = await connection.model('ad').find({ lineitemId: lineitem.id });
const activeAds = ads.filter(ad => ad.status === 'Active');

let haveDatesChanged = false;
if ($initialDates.type !== dates.type) {
haveDatesChanged = true;
} else if (dates.type === 'range') {
haveDatesChanged = dates.start.valueOf() !== $initialDates.start.valueOf()
|| dates.end.valueOf() !== $initialDates.end.valueOf();
} else {
const days = dates.days || [];
const initialDays = $initialDates.days || [];
haveDatesChanged = days.sort().toString() !== initialDays.sort().toString();
}
const query = {
$or: [
{ _id: { $in: ids.adunit } },
{ deploymentId: { $in: ids.deployment } },
{ publisherId: { $in: ids.publisher } },
],
deleted: false,
};
const adunits = await connection.model('adunit').find(query);

const activeStatuses = ['Running', 'Scheduled'];
if (hasStatusChanged) {
handleSchedules(this, activeStatuses.includes(this.status));
} else if (haveDatesChanged) {
handleSchedules(this, true);
}
const endDay = day => new Date(day.valueOf() + (24 * 60 * 60 * 1000) - 1);

const schedules = adunits.reduce((arr, adunit) => {
const elgible = activeAds
.filter(ad => ad.width === adunit.width && ad.height === adunit.height);

if (elgible.length) {
const winners = elgible.map(ad => ({ _id: ad._id, url: ad.url, src: ad.image.serveSrc }));
if (dates.type === 'range') {
arr.push({
lineitemId: lineitem._id,
adunitId: adunit._id,
priority,
start: dates.start,
end: dates.end,
ads: winners,
});
} else {
dates.days.forEach((day) => {
arr.push({
lineitemId: lineitem._id,
adunitId: adunit._id,
priority,
start: day,
end: endDay(day),
ads: winners,
});
});
}
}
return arr;
}, []);
schedules.forEach((schedule) => {
bulkOps.push({ insertOne: { document: schedule } });
});
return connection.model('schedule').bulkWrite(bulkOps);
});

schema.index({ name: 1, _id: 1 }, { collation: { locale: 'en_US' } });
Expand Down
9 changes: 5 additions & 4 deletions services/graphql/src/mongoose/schema/schedule.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const { Schema } = require('mongoose');

const schema = new Schema({
adUnitId: Schema.Types.ObjectId,
adunitId: Schema.Types.ObjectId,
start: Date,
end: Date,
lineItemId: Schema.Types.ObjectId,
lineitemId: Schema.Types.ObjectId,
priority: Number,
ads: [{
_id: Schema.Types.ObjectId,
Expand All @@ -13,7 +13,8 @@ const schema = new Schema({
}],
});

schema.index({ adUnitId: 1, start: 1, end: 1 });
schema.index({ adUnitId: 1, lineItemId: 1 });
schema.index({ adunitId: 1, start: 1, end: 1 });
schema.index({ lineitemId: 1 });
schema.index({ priority: 1 });

module.exports = schema;

0 comments on commit 77aa695

Please sign in to comment.