Skip to content

Instantly share code, notes, and snippets.

@mukulmishra18
Created April 1, 2018 20:58
Show Gist options
  • Save mukulmishra18/df706c4046c7ef59b6745f8af7465229 to your computer and use it in GitHub Desktop.
Save mukulmishra18/df706c4046c7ef59b6745f8af7465229 to your computer and use it in GitHub Desktop.
Pizza ordering service.
/** Pizza Service.
*
* When a new order will come handleOrder class can handle the task
* by checking if order can be fulfilled in the given time interval.
* For priority customer it is 15 minutes and for rest it is 30 minutes.
*
* -- When order can be flufilled handleOrder.ready = Unresolved promise.
* -- When order cannot be flufilled handleOrder.ready = Resolved promise.
* By doing this, incoming orders can wait for promise queue to fulfill.
* Orders are arranged in time series and handled as a first come first serve.
*
* TimeThread class works as a events bus that can emit time events.
* All the class can listen for this event and change the state of ready
* promise of each class based on the time to resolve or pending.
*/
function createPromiseCapability() {
let capability = {};
capability.promise = new Promise((resolve, reject) => {
capability.resolve = resolve;
capability.reject = reject;
});
return capability;
}
/**
* TimeThread class emits event on the event bus after each second.
* By doing this we can track each activity in time series.
*/
class TimeThread() {
constructor() {
this.eventBus;
this.currentTime;
}
// After each second emit events e.g. tick.
tick() {
}
}
/**
* Warehouse class keep track of the ingredient present.
* It can also order for more ingredients.
*/
class Warehouse {
constructor() {
this.dough = 10;
this.tomatoSauce = 10;
this.cheese = 10;
this.prosciutto = 10;
this.pepperoni = 10;
this.orderIngredients = new OrderIngredients();
// On each tick of TimeThread call autoFill to check if we
// can refill any of the ingredients in the warehouse.
}
// Auto fill the ingredients when it needed.
autoFill() {
this.orderIngredients.ready.then(() => {
let itemToOrder = this.getLeast();
this.orderIngredients.newOrder()
});
}
getLeast() {
// Return the ingredient who is least in amount.
}
}
class OrderIngredients {
constructor() {
// Initiall there is no ordering happening.
this.timeToFinish;
// Ready capability to notify if we can order new ingredient.
// Initially it is resolve promise.
this.readyCapability = createPromiseCapability();
this.readyCapability.resolve();
this.ready = readyCapability.promise;
}
newOrder() {
this.readyCapability = createPromiseCapability();
this.ready = readyCapability.promise;
// Resolve readyCapability after 10 minutes.
}
}
class PizzaRack {
constructor() {
// Initially pizza rack is free to use.
// Ready capability is show if we can use the rack to make pizza.
this.readyCapability = createPromiseCapability();
this.readyCapability.resolve();
this.ready = this.readyCapability.promise;
}
makePizza() {
this.readyCapability = createPromiseCapability();
this.ready = readyCapability.promise;
// Resolve readyCapability when current pizza is finsied to make.
}
}
class HandleOrder {
constructor() {
// Create 3 racks to make pizzas.
// As we can make atmost 3 pizzas at a time,
// we can treat it as a 3 separate rack to make pizza.
this.rack1 = new PizzaRack();
this.rack2 = new PizzaRack();
this.rack3 = new PizzaRack();
this.warehouse = new Warehouse();
this.isPriorityCustomer;
this.timeToFulFillTheOrder;
this.order = order;
// Promise notify if system can handle a new order.
this.readyCapability = new createPromiseCapability();
this.readyCapability.resolve();
this.ready = readyCapability.promise;
this.receipe = {
margherita: {
dough: 1,
sauce: 1,
cheese: 3,
prosciutto: 0,
pepperion: 0
},
proscoutto: {
dough: 1,
sauce: 1,
cheese: 0,
prosciutto: 2,
pepperion: 0
},
pepperion: {
dough: 1,
sauce: 1,
cheese: 1,
prosciutto: 0,
pepperion: 1
}
};
this.timeToMake = {
margherita: 5,
prosciutto: 7,
pepperion: 8
};
}
handle(isPriorityCustomer, order) {
this.isPriorityCustomer = isPriorityCustomer;
this.timeToFulFillTheOrder = isPriorityCustomer ? 15 : 30;
this.order = order;
// If order can be fulfilled set `ready` as pending promise.
if (canFulfill()) {
this.readyCapability = createPromiseCapability();
this.ready = this.readyCapability.promise;
}
}
canFulfill() {
// Check if the order can be fulfilled by calculating the total time needed
// to make the pizzas. The time to fulfill the order consists the time to make
// the pizzas plus the time to reorder the ingredients if not aviable in the warehouse.
}
}
let handleOrder = new HandleOrder();
// Fake listener for new order events.
// Event will fire with some data about the order.
document.addEventListener('newOrder', (event) => {
// Handle a new order when there is no previous order pending.
handleOrder.ready.then(() => {
handleOrder.handle(event.isPriorityCustomer, event.order);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment