11. #MM18DE
Command–query separation (CQS) is a principle
of imperative computer programming. It was devised
by Bertrand Meyer as part of his pioneering work on
the Eiffel programming language.
It states that every method should either be
a command that performs an action, or a query that
returns data to the caller, but not both. In other
words, Asking a question should not change the answer.
CQS
12. #MM18DE
class UserAccount
{
/**
* @var boolean
*/
private $isActive;
/**
* @return boolean Return true if active; otherwise return false
*/
public function isActive()
{
return $this->isActive;
}
/**
* @return void
*/
public function activate()
{
$this->isActive = true;
}
}
• Command methods change the state
• Commands do not return value (only
void)
• Query methods read the state
• Queries do not change the state of data
being used
• One object in a code for state changing
and querying data
35. • History
• Rebuild the State for any given point of time
• High Scalability
• Append Only operations
• Low-latency writes
• Allows asynchronous processing
39. Conway’s Law
Any organization that designs a
system (defined broadly) will
produce a design whose structure
is a copy of the organization's
communication structure.
-- Melvyn Conway, 1967
43. #MM18DE
Where did we start?
West
Central
East
Requests from
merchants and
partners
• Need Multiple
warehouses
• Can’t split inventory
for a single product
Current state
• Single stock only
• Must customize or
extend
• Can be complex to
manage and upgrade
Multiple types
needed
• Warehouses
• Stores
• Distribution Centers
• Drop Shipping
Increasingly common
• Even for smaller
merchants
• Applies to both B2C
and B2B
46. #MM18DE
Original internal Epic MAGETWO-14308
Progress!
Source management
Assign products and quantity
to sources
Priority-based selection
algorithm for shipment
Original internal Epic MAGETWO-14308
47. #MM18DE
Performance Degradation on order placement
which can’t be controlled, as computation of
Source Selection could be very time consuming
51. #MM18DE
Technical Overview
• MSI is a brand new way to handle inventory
• Event Sourcing + CQRS architecture
• Scalable Multi-Dimensional indexes for Stocks
• Usage of PHP 7.1 features
• Highly modular design
52. #MM18DE
Size of MSI Project
33 modules created in the scope of the project
Current Codebase of MSI Modules:
57 518 lines of PHP code
It is ~12% of the whole Magento Modules codebase
54. #MM18DE
Inventory Reservations in MSI
• When an order is placed, a reservation is made
to ensure there will be enough quantity
available to fulfill the order
• Reservations are append only operations to
prevent blocking operations and race conditions
at checkout
• The reservations table is periodically cleaned of
reservations that sum to zero
Merchant Benefits
Performant checkout even with high concurrent sessions
Prevents overselling available inventory
55. #MM18DE
Reservation Example – Step 1
France Warehouse
SKU-1: 5 qty
EU Stock
SKU-1: 15 qty
Italy Warehouse
SKU-1: 10 qty
Raw data Index Reservations
Salable Qty: 15 (data from index, empty reservations)
57. #MM18DE
Reservation Example – Step 3
France Warehouse
SKU-1: 5 qty
EU Stock
SKU-1: 15 qty
Italy Warehouse
SKU-1: 10 qty
Raw data Index Reservations
Salable Qty: 10 (data from index: 15, apply all reservations: -5)
Data is NOT changed
SKU-1: -5 Order #001
Reservation has been added
59. #MM18DE
Reservation Example – Step 5
France Warehouse
SKU-1: 5 qty
EU Stock
SKU-1: 15 qty
Italy Warehouse
SKU-1: 10 qty
Raw data Index Reservations
Salable Qty: 13 (data from index: 15, apply all reservations: -5+3)
Data is NOT changed Reservation has been added
SKU-1: -5
SKU-1: +3
Order #001
Return #001
60. #MM18DE
Reservation Example – Step 6
Actions:
• Admin ships remaining items in order (qty 2)
• Reindex on shipment of order
62. #MM18DE
Reservation Example – Step 7
France Warehouse
SKU-1: 3 qty
EU Stock
SKU-1: 13 qty
Italy Warehouse
SKU-1: 10 qty
Raw data Index Reservations
Salable Qty: 13 (data from index: 13, apply all reservations: -5+3+2=0)
Data is CHANGED
SKU-1: -5
SKU-1: +3
SKU-1: +2
Order #001
Return #001
Order #001 Shipment
Reservation has been added
63. #MM18DE
Reservation_id Stock_id sku quantity metadata
1 2 SKU-1 -5.000 order_placed:order:1
2 2 SKU-1 3.000 order_cancelled:order:1
3 2 SKU-1 2.000 shipment_created:order:1
Reservation Example – Step 8
Action:
• Reservation cleaning
• Looping through these reservations we can find reservations which
in sum return 0 (Zero) and remove them
64. #MM18DE
Reservation Example – Step 9 (like Step 1)
France Warehouse
SKU-1: 3 qty
EU Stock
SKU-1: 13 qty
Italy Warehouse
SKU-1: 10 qty
Raw data Index Reservations
Salable Qty: 13 (data from index, empty reservations table)
Data is NOT changed Reservations have been
removed
65. #MM18DE
Extension points and APIs in MSI
• For integration with ERP and PIM systems
• Inventory Sales API (Reservations placement)
• For extension developers
• Source Selection AlgorithmAPIs to provide own more efficient and business
oriented choice of Sources for order fulfillment
66. Microservices and MSI
• InventoryApi (APIs)
• Inventory
(Implementation for
APIs)
• InventoryAdminUi
• InventoryFrontendUi