Skip to content

Commit

Permalink
Cart Cleanup Job (#2013)
Browse files Browse the repository at this point in the history
* add cart-cleanup implementation

* import cart cleanup job and call its function

* update cart cleanup job to remove stale cart for anonymous user

* update registry schema to hold cart cleanup schedule and reminder

* add cart cleanup schedule and email reminder fields to view

* update reminder and cleanup field in shops settings to hold default values

* update select dropdown values and placeholder in view

* update cart cleanup job for users with account

* remove unnecessary field

* remove unnecessary field and fix indent issue

* refactor cart cleanup job

* remove dropdown and style fix

* proper naming field

* update job to cleanup anonymous user cart and account

* export session collection

* update cart cleanup job to clear anonymous user's session

* add cart cleanupDurationDays to reaction.json.example

* update job to run after settings has been loaded from reaction.json

* correct misleading placeholder

* refactor job to purge anonymous user stale carts/account/sessions

* add JSDoc for purge function

* add function that fetches stale carts

* implement review
  • Loading branch information
abdulsemiu-atanda authored and brent-hoover committed Mar 28, 2017
1 parent f5c3511 commit 03e63e4
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
{{> afQuickField name='settings.openexchangerates.refreshPeriod' placeholder="every 1 hour"}}
{{> afQuickField name='settings.google.clientId'}}
{{> afQuickField name='settings.google.apiKey'}}
{{> afQuickField name='settings.cart.cleanupDurationDays' placeholder="older than 3 days"}}
{{> shopSettingsSubmitButton}}
{{/autoForm}}
</div>
Expand Down
3 changes: 3 additions & 0 deletions imports/plugins/included/jobcontrol/server/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import "./jobs/exchangerates";
import "./jobs/cleanup";
import "./jobs/cart";
import cleanupJob from "./jobs/cleanup";
import fetchRateJobs from "./jobs/exchangerates";
import cartCleanupJob from "./jobs/cart";
import "./i18n";

cleanupJob();
fetchRateJobs();
cartCleanupJob();
87 changes: 87 additions & 0 deletions imports/plugins/included/jobcontrol/server/jobs/cart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import later from "later";
import moment from "moment";
import { Accounts, Cart, Jobs } from "/lib/collections";
import { Hooks, Logger, Reaction } from "/server/api";
import { ServerSessions } from "/server/publications/collections/sessions";


Hooks.Events.add("afterCoreInit", () => {
Logger.debug("Adding Job removeStaleCart and Accounts to jobControl");
const settings = Reaction.getShopSettings();
if (settings.cart) {
new Job(Jobs, "cart/removeFromCart", {})
.priority("normal")
.retry({
retries: 5,
wait: 60000,
backoff: "exponential" // delay by twice as long for each subsequent retry
})
.repeat({
schedule: later.parse.text("every day")
})
.save({
cancelRepeats: true
});
} else {
Logger.warn("No cart cleanup schedule");
}
});

/**
* {Function} that fetches stale carts
* @param {Object} olderThan older than date
* @return {Object} stale carts
*/
const getstaleCarts = (olderThan) => {
return Cart.find({ updatedAt: { $lte: olderThan } }).fetch();
};

export default () => {
const removeStaleCart = Jobs.processJobs("cart/removeFromCart", {
pollInterval: 60 * 60 * 1000, // backup polling, see observer below
workTimeout: 180 * 1000
}, (job, callback) => {
Logger.debug("Processing cart/removeFromCart");
const settings = Reaction.getShopSettings();
if (settings.cart) {
const schedule = (settings.cart.cleanupDurationDays).match(/\d/);// configurable in shop settings
const olderThan = moment().subtract(Number(schedule[0]), "days")._d;
const carts = getstaleCarts(olderThan);
carts.forEach(cart => {
const user = Accounts.findOne({ _id: cart.userId });
if (!user.emails.length) {
const removeCart = Cart.remove({ userId: user._id });
const removeAccount = Accounts.remove(
{
_id: cart.userId,
emails: []
}
);
const destroySession = ServerSessions.remove({ _id: cart.sessionId });
Meteor.users.remove({ _id: user._id, emails: [] }); // clears out anonymous user
if (removeCart && removeAccount && destroySession) {
const success = "Stale anonymous user cart and account successfully cleaned";
Logger.debug(success);
job.done(success, { repeatId: true });
}
} else {
Cart.remove({ userId: user._id });
const success = "Stale user cart successfully cleaned";
Logger.debug(success);
job.done(success, { repeatId: true });
}
});
} else {
Logger.warn("No cart cleanup schedule");
}
callback();
});
Jobs.find({
type: "cart/removeFromCart",
status: "ready"
}).observe({
added() {
return removeStaleCart.trigger();
}
});
};
5 changes: 5 additions & 0 deletions lib/collections/schemas/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ export const CorePackageConfig = new SimpleSchema([
"settings.public.allowGuestCheckout": {
type: Boolean,
label: "Allow Guest Checkout"
},
"settings.cart.cleanupDurationDays": {
type: String,
label: "Cleanup Schedule",
defaultValue: "older than 3 days"
}
}
]);
3 changes: 3 additions & 0 deletions private/settings/reaction.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"host": "",
"port": ""
},
"cart": {
"cleanupDurationDays": "older than 3 days"
},
"services": [{
"facebook": {
"appId": "",
Expand Down
3 changes: 2 additions & 1 deletion server/publications/collections/sessions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { Reaction } from "/server/api";
* If no session is loaded, creates a new one
*/

this.ServerSessions = new Mongo.Collection("Sessions");
export const ServerSessions = new Mongo.Collection("Sessions");
this.ServerSessions = ServerSessions;

Meteor.publish("Sessions", function (sessionId) {
check(sessionId, Match.OneOf(String, null));
Expand Down

0 comments on commit 03e63e4

Please sign in to comment.