Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Владимир Лобода "Как разделить монолит на части и выжить после этого"

Владимир Лобода "Как разделить монолит на части и выжить после этого"

Расскажу историю со счастливым концом о том, как мы переписывали подсистему подготовки данных для продуктов 2ГИС с VBA-скриптов, дробили монолит и интегрировали гетерогенный код в рамках одного приложения:
- как объединить разные источники данных с разной структурой
- как абстрагировать обработку данных и переиспользовать логику
- как интегрировать код разных команд на разных языках

DotNetRu

June 20, 2019
Tweet

More Decks by DotNetRu

Other Decks in Programming

Transcript

  1. • несколько источников однотипных данных • разные способы доставки •

    разная структура одних и тех же объектов Исходные данные #16
  2. • несколько источников однотипных данных • разные способы доставки •

    разная структура одних и тех же объектов • постоянные изменения структуры данных Исходные данные #17
  3. • разные форматы • постоянные изменения формата • агрегированные данные

    • сложная пред- и пост-обработка • требования на консистентность и валидность данных Потребители #22
  4. #28 public interface ISource : IDisposable { ISourceReader GetDeletedRows(); ISourceReader

    GetInsertedOrUpdatedRows(); byte[] GetDataVersion(); } public interface ISourceReader : IDisposable { bool Read(); object this[string columnName] { get; } }
  5. #29 internal class FirmSetSource : ISource { public ISourceReader GetDeletedRows()

    { if(_lastDataVersion == null) return null var query = DataContext.ExecuteObject<EsbFirmDeleted>(_lastDataVersion); return new DeletedIdsSourceReader<long>(query.Select(x => x.Id).GetEnumerator()); } public ISourceReader GetInsertedOrUpdatedRows() { return new EnumeratorSourceReader(typeof(FirmSet), GetNewRows().GetEnumerator()); } public virtual byte[] GetDataVersion() { return DataContext.ExecuteObject<EsbFirm>().Max(x => x.RowVersion); } }
  6. #32

  7. Intermediate text format #40 R[adm_div.region 1267655302447167] Text[Новосибирская область] Parent[adm_div.country 1]

    Weight[21986.56] Geometry[POLYGON((80.976493 54.314743,80.972756 ,80.969049 ...))] R[org 1267174266110329] Text[Авиакон Цитотранс] Field[][Авиакон Цитотранс] Field[HasWebsite][True] Feature[rubric 1266757654291981] Feature[organization_legal_form 1]
  8. Intermediate XML format #41 <Node node_id="154080025718444192" control="0"> <out_edge_ids> <edge edge_id="1"

    edge_uid_gtk="196775" edge_uid_pk="2" edge_fiji_id="845142189670401" /> </out_edge_ids> <in_edge_ids> <edge edge_id="2" edge_uid_gtk="196775" edge_uid_pk="3" edge_fiji_id="845142189670401" /> </in_edge_ids> <coordinates x="2093180" y="-3459699" z="0" /> </Node>
  9. Intermediate Sqlite format #42 CREATE TABLE geo_data ( id INTEGER

    NOT NULL, type INTEGER NOT NULL, geometry BLOB NOT NULL, attributes BLOB NULL, parent_id INTEGER NULL, PRIMARY KEY ( id ) ); CREATE INDEX idx_geo_data_type ON geo_data(type); CREATE INDEX idx_geo_data_parent_id ON geo_data(parent_id);
  10. • потребитель сам контролирует данные • меняет алгоритмы, когда хочет

    • легко решает проблемы • контролирует конфигурацию Плюсы #47
  11. • потребитель сам контролирует данные • меняет алгоритмы, когда хочет

    • легко решает проблемы • контролирует конфигурацию • может вносить изменения в intermediate format в любой момент Плюсы #48
  12. • требуется настройка окружения, в котором будет исполняться код •

    поддержка изменений в исходных данных со стороны экспорта требует времени и влияет на скорость поставки фич Сложности #50
  13. #52 DATA DATA DATA DATA DATA DATA Preparing Preparing Preparing

    Export Step 1 Export Step 2 Export Step 3
  14. #53 DATA DATA DATA DATA DATA DATA Preparing Preparing Preparing

    X Export Step 1 Export Step 2 Export Step 3
  15. #54 DATA DATA DATA DATA DATA DATA Preparing Preparing Preparing

    Export Step 1 Export Step 2 Export Step 3
  16. SP 1 #56 Source 1 Database SP1 Source 2 Source

    3 Export Весь процесс Часть, начиная от SP1
  17. SP 2 #57 Preparing 1 Database Preparing 2 Preparing 3

    Export Весь процесс Часть, начиная от SP2 Database SP2
  18. SP 3 #58 Process 1 Database Process 2 Process 3

    Export Весь процесс Часть, начиная от SP3 Result files (SP3) Export
  19. • используйте промежуточные форматы для интеграции с кодом сторонних команд

    Итоги #61 YOUR APP Intermediate format Foreign Code Foreign Code YOUR APP Foreign Code Intermediate format Intermediate format