Created
April 1, 2018 20:58
-
-
Save mukulmishra18/df706c4046c7ef59b6745f8af7465229 to your computer and use it in GitHub Desktop.
Pizza ordering service.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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