Pull to refresh
10
0
Оникийчук Антон @onikiychuka

User

Send message

Вопрос - а зачем тут IMediator? Можно же вот так написать:

namespace Vendor.Features.Statistics
{
  public class GetAutomationStatisticsResult
  {
    public long TotalAutomations { get; set; }
    public long ErrorsReported { get; set; }
    public long WarningsReported { get; set; }
  }

  public class GetAutomationStatisticsHandler 
  {
    private readonly GetAutomationsLogTotalCount _getAutomationsLogTotalCount;
    private readonly GetAutomationsTotalCount _getAutomationsTotalCount;

    public GetAutomationStatisticsHandler(
      // Это делегаты на другие фичи (этакая инкапсуляция над медиатром)
      GetAutomationsLogTotalCount getAutomationsLogTotalCount,
      GetAutomationsTotalCount getAutomationsTotalCount)
    {
      _getAutomationsLogTotalCount = getAutomationsLogTotalCount;
      _getAutomationsTotalCount = getAutomationsTotalCount;
    }

    public async Task<GetAutomationStatisticsResult> Handle(DateTime? FromDate, DateTime? ToDate, string TaskArn, CancellationToken ct)
    {
      // some logic
    }
  }

//не уверен что он нужен но пусть будет
  public delegate Task<GetAutomationStatisticsResult> GetAutomationStatistics(DateTime? FromDate, DateTime? ToDate, string TaskArn, CancellationToken ct = default);
}

В таком виде мы явно видим что вызываем, понятны параметры вызова. Намного проще переходить по коду. Я честно не могу понять какую пользу приносит именно IMediator в реализацию такого хендлера. Да я понимаю что есть валидация, транзакции, логирование в пайплайне. Если именно для этого - то понятно. Но если без пайплайна - то зачем?

Вкурсах. По этому пытаются перевести Blazor под wasm-unknown toolchain (через WASI-Libc) вместо emscripten. Только вот проект очень медленно стоит на месте. Emscripten - это 18й век, который нужен что-бы запускать сужествующие С приложения на wasm без особых изменений. Wasm-unknown - куда более нативный и быстрый. Ну и основная часть работы над wasm вне браузера (WASI) ведется как раз на Rust. Так что выбор очевиден. Для браузерных API поддержка в Rust тоже прекрасна.

#режим зануды включен

Сори но ваш процесс разработки в ветках это не Github-flow. Github-flow это хорошо описанный легковесный процесс для разработки. Процитирую автора:

Anything in the master branch is deployable

  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)

  • Commit to that branch locally and regularly push your work to the same named branch on the server

  • When you need feedback or help, or you think the branch is ready for merging, open a pull request

  • After someone else has reviewed and signed off on the feature, you can merge it into master

  • Once it is merged and pushed to 'master', you can and should deploy immediately

То есть как минимум в нем просто не может быть релиз бранчей - тк master по сути и есть релиз бранч.
#режим зануды выключен.

Мы понимаем DevOps как набор практик, с помощью которых фичакоманда может доставить свой продукт до конечного потребителя. Если кто-то делает это через зоопарк велосипедов (и это работает) — кто мы такие что-бы запрещать ковыряться в носу :)
У нас самих зоопарка если что нет :) k8s — наше все :)

Не очень понятно как при таком подходе будет обеспечивтаться сквозная аналитика всего хранилища. Получается, что все данные будут жить в своих silos и аналитика будет происходить на уровне каждого silos независимо.

Мы пока думаем как это сделать. И надо ли это делать вообще. Ведь вполне можно создать домен для ad-hook аналитики, с помощью которого можно решить 80% вопросов. А если задача не попадает под 80% стандартных — ну что-ж надо создавать узкий домен.


В одной из моих предыдущих компаний был такой подход: данные хранились и обрабатывались централизованно, однако у каждого data set был свой владелец (фича-команда), которые отвечал за наполнение этого сета свежими данными, а так же за публикации актуальной спецификации структуры данных. Спецификация хранилась в центральном репозитории в формате Protobuf.

Это тоже Data Mesh в нашем понимании. Основная идея для нас — чтобы не было господа-бога-данных, без которого нельзя решить ни один вопрос, касающийся данных.

Почитав ваши вопросы, мне показалось, что вам кажется что все что описано — внедрено внутри компании. Это пока не так :) Сейчас мы на примере одной команды разрабатываем процесс и инструменты для внедрения Data Mesh в Додо. Так что мои ответы будут основываться на том, как мы видим конечный результат внедрения сейчас, а не на рабочем процессе.


1 Как боретесь с дублированием данных в разных доменах? Как организовано их переиспользование? На первый взгляд создавать одинаковые датасеты для разных команд в режиме изоляции не выглядит оптимальным.

Никак. У нас нет такой задачи. Если это будет неоптимальным в будущем — будем думать. Как вариант — выносить в отдельный домен данных которым будет владеть команда Data Engeneering.


2 Датасеты BI команды строятся на данных из доменов продуктовых команд?

Не совсем. Например уже на этапе проектирования нам понадобился датасет который включает факты опубликованные несколькими сервисами. В данном конкретном случае — логика мерджа была сложная и использовалась в нескольких отчетах. Мы вынесли ее в отдельный домен.


3 Расскажите больше о том, как команды управляются внутри своих доменов. Используют airflow для etl задач? Кто пишет джобы? Как делят ресурсы?

Технически мы используем Azure Kusto и его Kql для ETL. Он очень быстрый и нам хватает его возможностей. Данные в Kusto попадают через публикацию сообщений в Event Hub.


4 Почему бы просто не раздать/обучить для каждой команды по data инженеру используя классический data lake подход? Насколько я понял, по сути, к этому все и пришло.

Пока не пришло :) Еще идем. Классический Data Lake подразумевает что есть команда, которая отвечает за всю аналитическую схему данных в компании. Даже если все в итоге будет длится в 1 Mysql (который будет Data Lake) но ответственность за схему будет делится между фичакомандами — это уже Data mesh. Подход не про технологии, а про организацию работы людей.

Но как быть с изменениями в логике данных? Простой пример: раньше в столбце «сумма чека» хранилась сумма без НДС, а потом в операционной системе что-то поменяли и стала храниться сумма уже с включенным НДС. С точки зрения продуктовой команды — это необходимое изменение, но при этом все потребители, которые опирались на этот показатель в data lake, сразу прибегут и скажут что у них сломались расчеты.

Так они у нас и текущим DataMonolith прибегают регулярно. Плюс мы сами чиним переливки в текущее аналитическое хранилище тк фича команда может удалить столбец без объявления войны :) Вообщем с монолитом еще хуже :)


Для написания тестов, которые будут проверять все возможные подобные случаи, надо будет потратить кучу времени — для каждой метрики или атрибута продумать возможные варианты использования, написать тесты, убедиться что они корректно работают при всех возможных раскладах и т.п.

Ну тут наверное подход будет похожим на TDD — сначала пишем тесты на требования, при нахождении багов — тесты на баги. Так хотя-бы не будем чинить одно и то-же дважды.


Мы понимаем что нет серебряной пули, но нам кажется что эти инструменты упростят нам жизнь.


Я искренне желаю чтобы у вас все получилось :) но из моего опыта часто при разделении ответственности за данные между разными командами начинается хаос. В основном потому, что каждой команде проще встать в позицию «моя хата с краю» и не думать про последствия изменений, которые они вносят.

Спасибо за теплые пожелания :) Мы приложим все силы что-бы получилось. Ну а хаос будет всегда — в наших силах только попытаться минимизировать ущерб от него через инструментарий и процесс :)

Нее в терминах CAP мы хотим построить CP систему. A в терминах CAP мы не гарантируем A но хотим стремится к минимальным простоям по доступности.
Распределенные транзакции — это все-таки про операционную деятельность. В аналитической мы стараемся иметь дело с набором случившихся фактов. Так что пока мы не видим необходимости в транзакциях. Хотя факты конечно могут (и будут) разезжаться если сопоставлять их по времени. Так что мы сейчас думаем как сопоставлять факты по foregin key.
Возможно вы правы. Но честно говоря я не вижу сильных проблем в дублировании, если оно не несет за собой проблемы другого рода (рассинхрон данных например). Если будет нести — придется наверное выделить НСИ в отдельный домен. В принципе за НСИ в операционной системе сейчас отвечает отдельный микросервис. Так что выделение их в отдельный домен вполне возможно.
Но есть ощущение, что не полностью раскрыт рабочий процесс при использовании нового подхода с data mesh.

Ну поскольку мы только начинаем его строить — раскрыть полностью процесс очень сложно в одной статье. Очень сложно раскрыть то, что полностью пока не сформировалось :) Сейчас мы итеративно выстраиваем процесс работы с данными внутри команды Data Engeneering, что-бы потом переносить его (естественно адаптирую) на всю компанию.
А в любой крупной компании таких зависимостей между данными разных систем будет очень и очень много, соответственно и разделить ответственность между продуктовыми командами будет непросто — все равно нужен «надсмотрщик», который будет разруливать зависимости и контролировать изменения.

На мой взгляд тут ситуация похожа с API микросервисов. Если API опубликован — в нем нельзя делать breaking changes. То же самое с опубликованными схемами данных. Как это форсировать и контролировать? Мы сейчас думаем про автоматические тесты, которые не дадут накатить миграцию если в ней есть breaking changes.
Да очень много дает.
Я ходил недавно на собеседование и как раз писал код на бумажке. Никаких проблем забываниями сигнатур API функций у интервьюверов не было. Достаточно примерно помнить что функция есть в стандартной библиотеке. А вот практические навыки твои видно просто прекрасно.
Например:
Решаем простую алгоритмическую задачку на java, которая свелась к fold (свертке списка). Ну я пишу 2 решения — одно циклами, другое на Stream API. Меня спрашивают — а как бы нам это сделать параллельно. Я отвечаю — можем использовать AsParallel в Stream API, но в общем это может быть медленнее(из-за кривизны Stream API), так что обязательно надо бенчмаркать. Просто смотря на код — фиг поймешь быстрее будет или медленнее.
Интервьювер сразу видит что я и код написать могу 2х стилях (функциональный и императивный) и то что неплохо знаю стандартную библиотеку java и границы применения ее API
Ну и если вы дете в команду интервьювера -ему же интересно как вы там КОД писать будете. Как переменные назвать (a, b, c или что-то более осмысленное), как методы. Насколько легко ему будет понять — что вы пишете.
Так что — имхо писать код на бумаге во время собеседования — одна из самых логичных практик.
Пишу одновременно на java и c# :)
В Java луше тк простой мапинг данных сделать в C# сложно
что-то из серии

Optional<User> user = ...;
Optional<UserName> name = user.map(u->new UserName(u.FirstName, u.LastName))


В C# будет выглядеть как

var user = ...
UserName name = null;
if(user != null) {
    name = new UserName(u.FirstName, u.LastName);
} 


Ну и в Java версии явно видно — может быть пустое значение или нет
Я всетаки отвечу.
Вот пришел я к вам в команду и вижу что вы используете DyUser. Это DynamicUser ( ну какой-то может быть очень активный) или DynamoUser — структура записи пользователя в DynamoDB? Часто бывает что из контекста это не понятно. В лучшем случае — я час проведу изучая код и пытясь понять что такое Dy, в худшем — пойду пытать вас. А у вас релиз завтра и пара противных багов висит. Но это еще «хорошие обревиатуры». Предположим что у нас есть еще бизнес обьекты типа Route и класс DyRoute — и это как раз тот самы Dynamic Route — он вообще относится к инфраструктуре и определяет куда нужно сейчас оправлять ваш запрос в зависимости от загрузки нижележащих сервисов. И ваще жопа — тк какого художника одна и таже обревиатура в разных кусках одного проекта означает соовсем не связанные между собой вещи.
Когда я был маленький, деревья большие и code-competion был только в emacs и контекстный — тогда сокращения имели смысл. На текущем витке развития software development — это примерно такой-же атавизм как и Go-To. Лучше про него просто забыть.
PS: Я не считаю что имена классов, обьектов или методов должны быть длинными. Совсем наоборот — они должны быть максимально корткими — но при этом читаемые. Такая вот задача минимизации — как не выплеснуть ребенка читаемости вместе с водой.
Посмотрел, ужаснулся именоваю классов, закрыл.
public final class App {
  public static void main(final String... args) {
    new FtBasic(
      new TkFork(
        new FkRegex("/robots.txt", ""),
        new FkRegex("/", new TkIndex()),
        new FkRegex(
          "/xsl/.*",
          new TkWithType(new TkClasspath(), "text/xsl")
        ),
        new FkRegex("/account", new TkAccount(users)),
        new FkRegex("/balance/(?<user>[a-z]+)", new TkBalance())
      )
    ).start(Exit.NEVER);
  }
}

FtBasic — что это???
TkFork — что это???
Что такое Ft или Tk? Зачем эти префиксы из аббревиатур?
Этот код читаем только потому что там есть пути к ресурсам. Количество WTF на момент прочтения readme зашкаливает. Я очень надеюсь что мы не будем писать код с таким именованием классов больше никогда.
Хмм можно разбирать вычисления из лямбд и по ним генерировать подписку.
interface IDisposableSupplier<T> : IDisposable {
  T Supply();
}
class ViewModel : BaseViewModel {
  public int A {get; set;}
  public int B {get; set;}
  private readonly IDisposableSupplier<int> cSupplier;
  public int C {get{ return cSupplier.Supply(); }}
  public ViewModel(){
       cSupplier = this.CreateSubcription(() => A + B);
  }
}
static class ProppertyChangedHelper {
   public static<T> IDisposableSupplier<T> CreateSubcription(this BaseViewModel vm, Expression<Func<T>> callable) {
  //AST parsing and subscriptions here.
 }
}
Ну а Linq в вашей команде используют — если что это монада List. Async/Await — тоже монада(название у нее разное в разных языках). Даже null value (использование null вместо значения по ссылке) — тоже монада.
Ну и самый главный прикол что просто последовательное исполнение кода в C# это тоже монада — в хаскеле ее называют IO.
Все пользуются монадами — не все об этом догадываются :)
К сожалению скандал не про выбросы. Volkswagen слишком быстро начал становится производителем машин #1 в мире (по количеству). Сейчас посмотрим как ребята из дружественных VAG партии зеленых в Германии начнут проверять пепелацы GM. Вот там смеху будет.
А если серьезно — причина не VW, а совершенно идиотские экологические нормы. Велосипедист который едет со скоростью 30-40 кмч дает больше вредных выбросов чем разрешено автомобилю в Калифорнии. Про стадо коров я вообще молчу. Но почему-то все привязались к автомобилям.
Проблема в том что весь мир живет по одним стандартам (MasterCard + Visa) а Германия по своему собственному (EC), карточку которого фиг получишь если ты не житель Германии. В этом и проблема, для тех кто в Германии не живет, а просто приезжает в гости.
Вы сравниваете совсем разные вещи.
Как минимум используя Linq можно писать запросы и к удаленному хранилищу и к любой локальной структуре данных в едином виде. Это очень полезно.
Jooq и querydsl — это возможность строить запросы к базе.
Тк я работал только с Jooq, то могу сказать только за него — синтаксис менее понятный чем у Linq.
Ну и с linq вся фишка в поддержке рантайма, а именно в том что вы можете получить доступ к AST лямбд которые вы передаете в Linq методы. Это позволяет писать куда более простой и читабельный код.
1
23 ...

Information

Rating
Does not participate
Location
Россия
Works in
Date of birth
Registered
Activity