Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP : Msi stock indexing #48 #49

Merged
merged 33 commits into from
Sep 1, 2017
Merged

WIP : Msi stock indexing #48 #49

merged 33 commits into from
Sep 1, 2017

Conversation

larsroettig
Copy link
Member

No description provided.

@larsroettig
Copy link
Member Author

@maghamed hi it is only basic version I think must also implement a bunching but the code is working some can be optimized. Have you a good example how can I test it?

@larsroettig larsroettig changed the title WIP : Msi stock indexing WIP : Msi stock indexing #48 Jul 30, 2017
@larsroettig larsroettig mentioned this pull request Jul 30, 2017
Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Big Merchants, who have a lot of SKUs and a lot of Sales channels (scopes in which products would be sold). We want to prevent a multiplication of data in the index table :
SKUs Qty * Number of Sales Channels

Because that could introduce performance impact both on Read and Write index operations.

That's why it's proposed to split indexes by the Scope.
Taking into account that we have 1 - 1 relation between Scope (Sales Channel) and Stock.
We could Build independent index table per each Stock (Stock_id).

Stock Id could be used as Dimension which will help us to resolve correct index we need to refer to get Product Qty.

For example, having 5 websites with ids (1 .. 5)
we will end up creating 5 different index tables (with the same structure):

inventory_stock_item_stock_1
inventory_stock_item_stock_2
inventory_stock_item_stock_3
inventory_stock_item_stock_4
inventory_stock_item_stock_5

You can refer for similar implementation in the CatalogSearch Index
Magento\CatalogSearch\Model\Indexer\Fulltext
Also, we have a requirement to have index aliasing during the full reindex happened, so we need to have switchable indexes to make Front-End responsive while Full Reindex happen.

Also, please take into account that when the SourceItem data change -> we need to upgrade Stock Item Indexes for each of the Stock to which given Source was assigned.
If Source was assigned to 3 stocks, for example, we need to refresh data in the 3 StockItem indexes

Looks like, for this operation we need to introduce new service
Magento\InventoryApi\Api\GetAssignedStocksForSourceInterface::execute($sourceId);

use \Psr\Log\LoggerInterface;
use \Magento\Framework\App\ResourceConnection;

abstract class AbstractAction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't introduce AbstractAction class, as Magento doesn't recommend to use Inheritance in newly created code.

Create a dedicated indexer model which would be injected via DI into each of the class:

Row
Rows
Full

and make each of these classes to proxy call to that indexer model

public function __construct(ResourceConnection $resource, LoggerInterface $logger)
{
$this->resource = $resource;
$this->connection = $resource->getConnection();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not recommended to make anything except assignment in the constructors.
Like in your case where you do
$this->connection = $resource->getConnection();

/**
* Stock item Indexer @todo
*/
class StockItem implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's wrong to Make indexer implementing both of these interfaces, because these interfaces responsible for different things. Doing so we violate Single Responsibility Principle.

We need to have two different classes, each one implementing own interface.

Like in CatalogSearch module
https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php
implements \Magento\Framework\Mview\ActionInterface
which is declared in - https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogSearch/etc/mview.xml#L9

and Magento\CatalogSearch\Model\Indexer\Fulltext implements only \Magento\Framework\Indexer\ActionInterface
which is declared in
https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogSearch/etc/indexer.xml#L9

Let's do the same way

$indexItems = $this->fetchIndexItems($sourceItems);
if (is_array($indexItems) && count($indexItems) > 0) {
$this->cleanIndexTable($sourceItems);
$this->updateIndexTable($indexItems);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to introduce implementation of IndexerInterface
https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Indexer/SaveHandler/IndexerInterface.php

and use it for the operations of clean and delete index


use Magento\InventoryApi\Api\Data\StockItemInterface;

class CreateStockItemIndexTable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be implemented similarly to what we have in CatalogSearch
where
Magento\CatalogSearch\Model\Indexer\IndexStructure
responsible for creating StockItem index structure.

IndexStructure implements interface
Magento\Framework\Indexer\IndexStructureInterface

we will reuse this class for index structure creation because we will create dedicated index table for each particular Stock (stock_id). To make the system being scalable horizontally.
As each index table will hold StockItems for each particular Scope (SalesChannel).

For example, having 5 websites each of which represents Sales Channel we will end up with 5 index tables:

inventory_stock_item_index_1 - for website_id 1 
inventory_stock_item_index_2 - for website_id 2
inventory_stock_item_index_3 - for website_id 3
inventory_stock_item_index_4 - for website_id 4
inventory_stock_item_index_5 - for website_id 5

try {
$this->reindexRows($ids);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()), $e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not correct translation,
__($e->getMessage()), $e);
Because \Exception $e ,so it's not a successor of Localized Exception, thus $e->getMessage()
could return a string for which you don't have precise translation

try {
$this->reindexRows([$id]);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()), $e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not correct translation,
__($e->getMessage()), $e);
Because \Exception $e ,so it's not a successor of Localized Exception, thus $e->getMessage()
could return a string for which you don't have precise translation

*
* @return void
*/
public function execute($id = null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we allow to accept NULL value if we throw an exception if NULL passed as a parameter?

* Interface StockItemInterface
* @api
*/
interface StockItemInterface extends ExtensibleDataInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now we don't have a Service API to retrieve Stock Items for a given Stock_ID

That's why for now we can't get StockItems in any case
These API should be introduced to InventoryApi\Api\StockItemManagerInterface

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
<indexer id="inventory_stock_item" view_id="inventory_stock_item" class="Magento\Inventory\Model\Indexer\StockItem">
<title translate="true">StockItem</title>
<description translate="true">Index stock item</description>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide more clear description

Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general everything good, @larsroettig please keep going

* @var string
*/
const DATA_KEY_INDEXER_ID = 'indexer_id';
const DATA_KEY_INDEXER_SUFFIX = 'indexer_suffix';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to make these fields as constants, because constants are the contract which could be accessible outside of the class (like public methods)

it's better to make them private static in this case, so, no one from outside could rely on these values.
And we will not duplicate these data for all instantiated classes.

* @param int $batchSize #
*/
public function __construct(
IndexStructure $indexStructure,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's better to use IndexStructureinterface here and specify in DI Type what exact implementation should use here

Batch $batch,
ResourceConnection $resource,
array $data,
$batchSize = 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use DI Type configuration for batchSize, especially taking into account that you will use Type for IndexStructure

/**
* Indexer ID in configuration
*/
const INDEXER_ID = 'inventory_stock_item_index';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm... it's better to keep this constant away from the concrete implementation, but for now I don't see a place where we could move it

private function getIndexSuffix()
{
if (isset($this->data[self::DATA_KEY_INDEXER_SUFFIX])) {
return $this->data[self::DATA_KEY_INDEXER_SUFFIX];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can we set these data?

/**
* Stock item Indexer @todo
*/
class StockItem implements \Magento\Framework\Indexer\ActionInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's introduce

interface StockItemIndexerInterface extends \Magento\Framework\Indexer\ActionInterface
{
    /**
      * Indexer ID in configuration
      */
     const INDEXER_ID = 'inventory_stock_item_index';
}

and make this class to implement this interface.

But Ideally to have getName method in ActionInterface which returned value initialized from the configuration, which we can't add because of BackwardCompatibility

*
* @codeCoverageIgnore
*/
class StockItemManager extends AbstractExtensibleModel implements StockItemManagerInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have StockItemManager which behaves like DataInterface,

Manager means to make some actions over some data.

* Interface StockItemManagerInterface
* @api
*/
interface StockItemManagerInterface extends ExtensibleDataInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this DataInterface?
it duplicated StockItemInterface, but called manager and never used

looks like a mistake

private function getAssignedStockIds($sourceId)
{
$searchCriteria = $this->searchCriteriaBuilder
->addFilter(StockSourceLink::SOURCE_ID, (int)$sourceId)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast to int is extra

/**
* Get all linked StockIds by given sourceId.
*
* @param $sourceId
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed parameter type

use Magento\Inventory\Model\Indexer\StockItem\IndexStructure;

/**
* Stock item Indexer @todo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls delete or add more description to @todo annotation

Batch $batch,
ResourceConnection $resource,
array $data,
$batchSize = 100
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move default value to di configuration

/**
* @var array
*/
private $data;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to more clear name?
What is mean data?

*
* @codeCoverageIgnore
*/
class StockItemManager extends AbstractExtensibleModel implements StockItemManagerInterface
Copy link

@naydav naydav Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for me *Manager is not good name for "entity"
Maybe it is better simple "StockItem"

But pay attention we already have \Magento\InventoryApi\Api\Data\StockItemInterface

public function setStockId($stockId);

/**
* Get stock item sku
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not stock item sku

interface GetAssignedStocksForSourceInterface
{
/**
* Get Stock assigned to Sources
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visa versa
Get Stocks assigned to Source

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
<view id="inventory_stock_item" class="Magento\Inventory\Model\Indexer\Mview\StockItemAction" group="indexer">
<subscriptions>
<table name="inventory_source_item" entity_column="source_id" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to process disabling/enabling of products?

/**
* StockItem constructor.
* @param DimensionFactory $dimensionFactory
* @param StoreManagerInterface $storeManager
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update doc block.

{

const TABLE_NAME_SOURCE_ITEM = 'inventory_source_item';
const TABLE_NAME_STOCK_SOURCE_LINK = 'inventory_source_stock_link';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe constants.
More info is available in the devdocs

* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
* @return string
*/
private function getSourceItemTableName($connection)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a type hint

* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
* @return string
*/
private function getLinkTableName($connection)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a type hint

* See COPYING.txt for license details.
*/

namespace Magento\Inventory\Model\Indexer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to have a separate namespace for Indexer. Not to put all indexers to
Magento\Inventory\Model\*

Let's create dedicated namespace like

Magento\Inventory\Indexer\

$storeIds = array_keys($this->storeManager->getStores());

foreach ($storeIds as $storeId) {
$dimension = [$this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId])];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the documentation https://github.com/magento-engcom/magento2/wiki/New-Indexer-for-StockItems#index-dimensions stated

That's why it's proposed to split indexes by the Scope. Taking into account that we have 1 - 1 relation between Scope (Sales Channel) and Stock
For example, having 5 websites with ids (1 .. 5) we will end up creating 5 different index tables (with the same structure):

inventory_stock_item_stock_1
inventory_stock_item_stock_2
inventory_stock_item_stock_3
inventory_stock_item_stock_4
inventory_stock_item_stock_5

Current code where dimension is StoreId is copy-pasted from Search Indexer

/**
* Stock Item Dimension
*/
class Dimension extends \Magento\Framework\Search\AbstractKeyValuePair
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already have
\Magento\Framework\Search\Request\Dimension
why do we create own Dimension object?

* depending on current scope state
* @todo refactoring it copy from catalog search module
*/
class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls provide more clear class name
class name is proxy, class interface is resolver, due to code it is factory... it is not clear what is responsibility of this class

if (!array_key_exists($state, $this->states)) {
throw new UnknownStateException(__("Requested resolver for unknown indexer state: $state"));
}
return $this->objectManager->create($this->states[$state]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to create a new object each time?

private function create($state)
{
if (!array_key_exists($state, $this->states)) {
throw new UnknownStateException(__("Requested resolver for unknown indexer state: $state"));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is better to place in State object. In this way, we don't provide possibility to set the wrong state

But if we look code of State object, we can not find possibility to set the wrong state.
In State objectwWe have only useTemporaryIndex and useRegularIndex methods, thus we can not set state different from these two.
So this checking looks like redundant

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree with @naydav in the scope of UnknownStateException I described the idea of State Machine, so don't think that we need to check the state and have a factory for state creation

* Resolves name of a temporary table for indexation
* @todo refactoring it copy from catalog search module
*/
class TemporaryResolver implements \Magento\Framework\Search\Request\IndexScopeResolverInterface
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that is taken from search index but I don't like naming (TemporaryResolver, IndexScopeResolver, ScopeProxy)
@maghamed what do you think about this naming?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav makes sense, naming should be aligned to outline the best practices and make it understandable for external developers what's the responsibility of the class reading its name.

* @todo refactoring it copy from catalog search module
* @api
*/
class UnknownStateException extends LocalizedException
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to think about moving this exception to framework lib if we will use it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav agree, already pointed that out for IndexTableNotExistException.
These should be framework level exceptions, we can't provide them to client because they provide details of how this functionality is implemented (leaky abstractions).

So, these exceptions are not successors of Localized

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I don't know why we have this Exception in our codebase.
So, from what I see we have a pre-defined finite list of states which could be switched in pre-defined order. (aka State machine design pattern)

  • our state object initially being initialized in 'REGULAR' state.
  • after that, we've decided to move it to 'TEMPORARY' state while making re-indexation
  • after re-indexation complete - we move the object to 'REGULAR' state again.

Is it correct? I suppose so, then why do we have a possibility that State object would be created in a wrong state?
@larsroettig


/**
* @magentoDbIsolation disabled
* @magentoDataFixture Magento/Inventory/_files/products.php
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is better to use one fixture with all preconditions

->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);

/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryFactory */
$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you create an instance of repository each time?

* See COPYING.txt for license details.
*/

\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can reuse fixture from catalog module

@@ -0,0 +1,66 @@
<?php
/**
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have this fixture
app/code/Magento/InventoryApi/Test/_files/source/source_list.php

@@ -0,0 +1,38 @@
<?php
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

app/code/Magento/InventoryApi/Test/_files/source/stock_list.php

larsroettig added 17 commits August 22, 2017 17:00
- Add Setup for index table
- Add new Interface"
- Refactoring to new Setup structure
- Implement SourceItem add entry to di.xml
- WIP Register Basic Indexer SourceItem
- Impelemnt basic import funktion

TODOS:
- Add some bunching function for index
- Add Mysql Index to  inventory_stock_item_index table
- Documentation and clean up
- Clean Up and implement basic structure
- Impelemnt basic import function

TODOS:
- Index switch from tmp to idx table
- Documentation and clean up
- Add Setup for index table
- Add new Interface

I magento-engcom/magento#48:
- Add Setup for index table
- Add new Interface
- Implement switch for Index

TODO:
- Clean Up and more Doc
- Discuss the missing website to stock mapping
- Impelemnt Basic intigration test fixtures
- Bugfix for di.xml
- Add basic call for reindex full
- Basic Indexer with switch for tmp and normal index

TODO:
- Refactoring to remove the state folder from the module
- Doc blocks and clean up
- Add assertions to the test case
-- fixes after merge
@magento-cicd2
Copy link

magento-cicd2 commented Aug 22, 2017

CLA assistant check
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ larsroettig
❌ naydav

Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav please help @larsroettig
and join this story development.

It's very sophisticated Story, and there are no good examples in Magento where re-indexation was implemented totally correct.

So, let's make a good example of introducing New Index to the Magento 2. Outlining all the steps and document them afterwards.

We already agreed that ActiveTableSwitcher would be moved to Framework maybe we need some additional things to move to the framework level?

* @todo refactoring it copy from catalog search module
* @api
*/
class IndexTableNotExistException extends LocalizedException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are introducing IndexTableNotExistException, this exception should be low-level (framework level).
Not inherited from LocalizedException.
Because we can't provide this Exception o the client code, even its name is a leaky abstraction of the internal details.

@@ -0,0 +1,24 @@
<?php
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Magento there is another Switcher mechanism - https://github.com/magento-engcom/magento2/blob/develop/app/code/Magento/Catalog/Model/ResourceModel/Indexer/ActiveTableSwitcher.php

by our request, it would be moved to the Framework soon (in the scope of Magento 2.2.0 regression).
So, we could consider using ActiveTableSwitcher for our purposes.

@naydav please consider this and provide a solution for @larsroettig

maybe we need some additional classes to be moved to the Framework?

* Resolves name of a temporary table for indexation
* @todo refactoring it copy from catalog search module
*/
class TemporaryResolver implements \Magento\Framework\Search\Request\IndexScopeResolverInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav makes sense, naming should be aligned to outline the best practices and make it understandable for external developers what's the responsibility of the class reading its name.

* @todo refactoring it copy from catalog search module
* @api
*/
class UnknownStateException extends LocalizedException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav agree, already pointed that out for IndexTableNotExistException.
These should be framework level exceptions, we can't provide them to client because they provide details of how this functionality is implemented (leaky abstractions).

So, these exceptions are not successors of Localized

* @todo refactoring it copy from catalog search module
* @api
*/
class UnknownStateException extends LocalizedException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I don't know why we have this Exception in our codebase.
So, from what I see we have a pre-defined finite list of states which could be switched in pre-defined order. (aka State machine design pattern)

  • our state object initially being initialized in 'REGULAR' state.
  • after that, we've decided to move it to 'TEMPORARY' state while making re-indexation
  • after re-indexation complete - we move the object to 'REGULAR' state again.

Is it correct? I suppose so, then why do we have a possibility that State object would be created in a wrong state?
@larsroettig

private function create($state)
{
if (!array_key_exists($state, $this->states)) {
throw new UnknownStateException(__("Requested resolver for unknown indexer state: $state"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree with @naydav in the scope of UnknownStateException I described the idea of State Machine, so don't think that we need to check the state and have a factory for state creation

larsroettig and others added 15 commits August 26, 2017 23:05
- Add test for index row
# Conflicts:
#	app/code/Magento/Inventory/etc/di.xml
- refactoring
- refactoring
- refactoring
- refactoring
- refactoring
- refactoring
- refactoring
- refactoring
- refactoring
- fix static tests
- update db structure
- fix static tests
@naydav
Copy link

naydav commented Sep 1, 2017

Internal build
https://bamboo.corp.magento.com/browse/M2-AT2478-3

@maghamed
Copy link
Contributor

maghamed commented Sep 1, 2017

Approved to be merged into the Develop branch

Great job guys @larsroettig @naydav , well done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants