пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
Слишком длинный поисковый запрос.
По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:
Конечно, распределенные системы и системы на основе микрослужб вносят большой вклад и позволяют расширить ваши возможности, но при этом вам придется приложить немало усилий для того, чтобы все эти отдельные элементы могли работать вместе. Jaeger – это инструмент с открытым исходным кодом, который предоставляет возможность трассировки и локализации проблем, и он определенно заслуживает внимания. Любой, кто занимается разработкой распределенных систем/микрослужб, должен знать, что такое Jaeger.
Хотите узнать больше? Тогда прочитайте эту статью. Здесь мы расскажем о трассировке, о том, что это значит, о важности этого понятия и т.д. Давайте начнет с основной идеи Jaeger.
Что такое трассировка распределенных систем?
Если мы говорим о Jaeger, значит, речь здесь пойдет о трассировке, и лучше всего разобраться, что же это значит, с точки зрения распределенных систем. Самая большая проблема – это объединить различные элементы и обеспечить возможность непрерывного взаимодействия между всеми этими микрослужбами.
В этом плане самым простым вариантом является монолитная архитектура, поскольку вам нужно работать только с одним компонентом. Если мы говорим о системах на основе микрослужб и распределенных системах, то здесь разработчики должны следить за потоком данных между двумя и более микрослужбами.
И тут на первый план выходит трассировка распределенных систем, так как она гарантирует, что данные, которые распределены между несколькими службами, доступны на централизованной платформе. Существует и другой способ понять, как это работает; у вас есть возможность наблюдения за каждым событием, которое происходит в рамках микрослужб.
Трассировка распределенных систем отлично помогает в том, что касается оптимизации и отладки, так как отслеживает важные данные и их поток.
По большому счету, это часть сервисной сетки, которая играет немаловажную роль в управлении микрослужбами. Это ключевая функция Jaeger, так как инструмент использует ее для того, чтобы отслеживать пути обработки запросов. Кроме того, такая концепция помогает уменьшить время отклика, проводить мониторинг распределенных транзакций и помогает в провидении анализа первопричин.
Что такое Jaeger: значение и обязанности
В принципе, это решение, предназначенное для трассировки распределенных систем, довольно часто используется для мониторинга и устранения неполадок в микрослужбах. Он визуализирует события, которые происходят в рамках микрослужб, для того, чтобы их можно было легко интерпретировать. У этой концепции есть еще одно название – Jaeger Tracing (трассировка Jaeger), так как она запускается вслед за отслеживанием путей обработки запросов и трассировками.
Это один и ключевых этапов разработки микрослужб. Мы все прекрасно знаем, что микрослужбы имеют несколько автономных приложений, у которых есть свои RESTful API, логика и база данных, и для того, чтобы взаимодействовать друг с другом, они отправляют запросы и отвечают на них.
Jaeger сортирует все по трассировкам и журналам. Вот основные обязанности Jaeger:
Поддержка перемещения данных внутри и за пределами экосистемы микрослужб
Выявление проблем, которые снижают производительность
Выяснение первопричины
Отслеживание всех компонентов, от которых зависят микрослужбы
Поддержка передачи распределенного содержимого, чтобы приложение, о котором идет речь, могло передавать содержательную информацию с соответствующими данными.
Компоненты Jaeger
Инструментарий
Этот компонент предназначен для формирования телеметрических данных. В данном случае это данные трассировки, данные журналов и метрики. Для формирования телеметрических данных используется код приложения. С помощью инструментария вы можете получить телеметрические данные, которые потом помогут вам в изучении ошибок.
В большинстве случаев инструментарий включает в себя такие инструменты, как SDK, агенты и клиентские библиотеки. Если мы говорим о Jaeger, то здесь также есть библиотеки на основе API OpenTracing.
Компоненты Jaeger
Раньше OpenTracing работал сам по себе, а позже он объединился с OpenTelemetry. У Jaeger есть несколько клиентских библиотек, в основе которых лежат такие языки, как Java, Go, C++, Node.js и C#. Не забывайте о том, что служба начинает генерировать отрезки входящих транзакций сразу после инструментрирования.
Веб-интерфейс пользователя/визуализация
Стандартный пользовательский интерфейс Jaeger становится универсальным, как только он становится частью трассировки распределенных систем.
Конвейер данных
Конвейер данных – еще один компонент Jaeger, который помогает принимать данные различных форматов. Когда службе удается собрать данные трассировки, она направляет их непосредственно во внутреннее хранилище для того, чтобы их можно было визуализировать. Если вы оставите данные на этом этапе без контроля, то могу произойти некоторые сбои.
На данном этапе Jaeger использует конвейер данных. Он отслеживает буферизацию данных и поддерживает такие вещи, как пакетная обработка, организация очереди, индексирование и манипулирование данными.
Внутреннее хранилище
Jaeger прибегает к помощи простого внутреннего хранилища для того, чтобы данные можно было использовать для тестирования. Есть два самых известных хранилища данных трассировки, которые использует Jaeger: Cassandra и ElasticSearch.
Выборка
Процесс выборки – это неотъемлемая часть Jaeger и его библиотек. Клиенты Jaeger могут выбить стратегии выборки и менять частоту выборки с помощью таких стратегий, как const sampler (постоянная выборка), probabilistic sampler (вероятностная выборка), opentracing.jaeger.const-sampler.decision = true | false, rate-limiting sampler (выборка с ограничением скорости) и т.д.
В то время как кто-то пытается разобраться, что же такое выборка Jaeger, важно усвоить тот факт, что это довольно сложная концепция и она используется в двух местах.
Давайте рассмотрим более подробно.
Выборка на уровне дистрибутива (SDK)
У выборки, которая происходит на уровне клиентского кода или SDK, есть еще одно название – головная выборка. У нее есть четыре режима.
Удаленный сэмплер (1-й режим – по умолчанию)
: с помощью этого режима клиенты Jaeger могут убедиться в том, что выборка была перемещена из внутреннего хранилища Jaeger, а, значит, с ней можно работать дальше.
Постоянный сэмплер
: дает указание клиенту либо принять все трассировки, либо ни одной. Другого варианта нет. Если выбраны все трассировки, то отображается 1, в противном случае, в качестве результата отображается 0.
Сэмплер с ограничением скорости
: здесь клиент может определить количество отбираемых трассировок в секунду.
Вероятностный сэмплер
: здесь клиент может выбрать наиболее оптимальный процент отбора трассировок.
Выборка на уровне сборщика
Здесь есть два режима. Другое название такой выборки – хвостовая выборка.
Первый режим –
файловая выборка
. Здесь речь идет об указании сборщику пути к файлу конфигурации. Файл, о котором идет речь, как правило, содержит данные конфигурации выборки для каждой операции и для каждой службы.
Еще один режим –
адаптивная выборка
, в основе которой лежит адаптивный сэмплер. Так, а что это такое? Это комбинированный сэмплер, который объединяет в себе две ключевые функции процесса выборки.
Процесс выборки на этом уровне происходит в сборщике Jaeger.
Например, это очень помогает при принятии решений о выборке на основе концепции каждой операции. Как правило, этот метод применяется в тех случаях, когда используются API с несколькими оконечными точками.
Кроме того, он отлично помогает при определении предельного значения частоты выборки. В таком случае каждое действие базируется на параметрах каждой отдельной службы, которые можно с легкостью настроить статически. Также этот параметр можно извлечь из внутреннего хранилища Jaeger с помощью удаленного сэмплера.
Сборщик создает экземпляр трассировки, используя стратегии статической выборки. В данном случае используется параметр --sampling и файл выбора стратегий.
Прощание с клиентом Jaeger в пользу дистрибутива OpenTelemetry
Недавно появилась новость о появлении OpenTelemetry, которая всколыхнула сообщество Jaeger, так как он поддержал объединение OpenCensus и OpenTracing. И даже после этого объединения Jaeger развертывает OpenTracing. Что же это значит?
Для начала нужно понимать, что трассировка Jaeger тесно связана со спецификацией OpenTracing. Популярность Jaeger резко снижается вследствие определенных трудностей. Уже имеющиеся клиенты Jaeger не отдали свое предпочтение SDK OpenTelemetry, так как он позволяет использовать совместимый язык. Кроме того, экспортер Jaeger может использоваться неправильно.
Экспортер Jaeger создает отрезки при трассировке распределенных систем и преобразует их в удобный формат. Такие отрезки можно легко перемещать между хранилищем и сборщиком Jaeger.
Сейчас еще рано делать какие-то выводы о том, стал ли OpenTelemetry полной заменой сборщика трассировок Jaeger. Но он вполне может стать таковым в будущем, так как Jaeger растерял свою популярность.
OpenTelemetry без каких-либо проблем справляется со всеми нюансами Jaeger, а также предоставляет пользователям единый стандарт с богатыми функциональными возможностями. Сообщество разработчиков полюбило этот дистрибутив за его уникальные функции, например, полную совместимость с предыдущими версиями OpenTracing и OpenCensus, а также за то, что в нем нет всяких ненужных функций. Он работает как цельная платформа наблюдения и упрощает вашу работу, что нельзя сказать о нативном облачном инструменте Jaeger.
Ограничения при использовании Jaeger в качестве инструмента трассировки распределенных систем
Существует довольно много вариантов, как можно использовать Jaeger, но у него есть определенные ограничения, так как полное устранение неполадок требует доступа к нескольким метрикам, а также к трассировкам. Сюда относятся метрика времени отклика, метрика загрузки ЦП, метрика частоты возникновения ошибок и т.д. Эти показатели помогают лучше понимать общее состояние приложения.
Jaeger не может отслеживать эти метрики, соответственно, у него есть несколько недостатков. Например,
Он будет только отслеживать данные, а пользователям придется прибегнуть к помощи специальных инструментов для отслеживания показателей и управления журналами. Если вы будете использовать для одной и той же задачи больше, чем один инструмент, то ваша работа будет выглядеть довольно коряво.
Обслуживание баз данных, которые использует Jaeger, должно быть на высшем уровне.
На вид этот инструмент не очень привлекательный, так как у него довольно простой веб-интерфейс.
С его помощью нельзя получить идеальное и быстрое понимание ключевых данных.
Альтернативы трассировки Jaeger
Чтобы обойти недостатки Jaeger, пользователи могут рассмотреть несколько альтернативных вариантов, которые вполне заслуживают внимания, например,
Aspecto – это платформа трассировки распределенных систем, которая имеет высокую степень совместимости с OpenTelemetry. Эта платформа способна сразу устранять неполадки и отслеживать производительность. Таким образом, вы можете отслеживать жизненный цикл ошибки, продолжая при этом вести журналы и выполнять трассировку.
Lightstep выбирают те, кому нужен централизованный инструмент для наблюдений и реагирования на инциденты. С его помощью IT-команды могут разрешать инциденты, не прерывая отслеживание данных и сбор метрик. Таким образом обеспечивается отличная наблюдаемость системы. А такие функциональные возможности, как аналитика изменений и Блокнот (Notepad), во многом упрощают работу.
Logz.io чем-то похож на Lightstep. Он предоставляет несколько доволнительных возможностей для тех, кто лояльно относится к Jaeger и ищет более управляемую поддержку. У него есть информационная панель для оповещений и мониторинга служб в режиме реального времени.
Заключение
Разумнее всего будет использовать Jaeger для разработки микрослужб и распределенных систем, так как с его помощью можно отслеживать данные и события. Но это не самое идеальное решение, так как, устраняя неполадки и управляя службами, он не может отслеживать метрики.
Но всегда есть альтернативные варианты. Сфокусируйте свое внимание на целях вашей разработки и подготовьте эффективную систему отслеживания данных, журналов и метрик для более надежного взаимодействия.
В сегодняшней статье рассмотрим модуль, который позволяет просматривать детальную информацию о сервере IP-АТС Asterisk и о процессах, которые на нем запущены прямо из web-интерфейса FreePBX - Asterisk Info. Все примеры в данной статье будут приводиться с использованием FreePBX 13. Ту же самую информацию можно получить, используя командную строку Asterisk – CLI (Command Line Interface). Сразу отметим, что данная информация будет понятна и полезна только продвинутым пользователям Asterisk и системным администраторам, например, при траблшутинге проблем.
Модуль Asterisk Info
Перейдём в модуль и рассмотрим его функционал. Модуль доступен по следующему пути с главной страницы Reports -> Asterisk Info
Как только мы переходим в модуль, перед нами открывается страница Summary. Здесь находится следующая информация:
Uptime – Показывает как долго сервер работает без отключения и рестарта
Reload - Показывает, когда последний раз была выполнена перезагрузка сервера. Перезагрузка происходит после нажатия на кнопку Apply Config, которая появляется после внесения изменений в конфигурацию через вэб-интерфейс
Active SIP Channels -Показывает, как много на сервере активных SIP каналов. Не надо путать с активными звонками.
Active IAX2 Channels – Показывает количество активных IAX2 каналов
SIP Registry - Показывает количество SIP транков, которые зарегистрированы на сервере
IAX2 Registry - Показывает количество IAX2 транков, которые зарегистрированы на сервере
SIP Peers - Показывает количество зарегистрированных SIP пиров. Пир – это внутренний номер (Extension) или транк (Trunk)
IAX2 Peers - Показывает количество зарегистрированных IAX2 пиров.
Справа можно выбрать другой тип отчета.
Registries
Данный отчет показывает каждое соединение, на которое зарегистрирован сервер Asterisk. Обычно здесь находится информация о транках. Этот отчёт показывает, на что зарегистрирован сервер, но не что зарегистрировано на нем, эту информацию следует искать во вкладке Peers.
Channels
Здесь выводится информация о каждом активном канале на сервере. Канал – это одно двустороннее соединение между двумя устройствами.
Peers
Здесь выводится информация о каждом устройстве, транке, внутреннем номере, которое зарегистрировано на сервере Asterisk.
SIP Info
Данный отчёт суммирует предыдущие два Registry и Peers, но выводит информацию только по SIP.
IAX Info
Данный отчёт суммирует Registry и Peers, но выводит информацию только по IAX2.
Conferences Report
Данный отчёт показывает информацию о любых активных конференциях на сервере.
Subscription Report
Показывает список всех подсказок (hints), которые созданы на сервере. Подсказка это то, на что подписана BLF кнопка на телефоне.
Voicemail Users Report
Показывает информацию о голосовой почте пользователей. Например, как много новых сообщений поступило.
Queues
Показывает информацию по очередям. Например, сколько сейчас звонков находится в очереди.
Full Report
Показывает информацию из всех предыдущих вкладок в одном окне.
Позвольте, я расскажу вам одну историю. Однажды я создавал очередной элемент выбора даты для нашей системы проектирования. Он состоит из поля текстового ввода и всплывающего окна с календарем, которое появлялось при нажатии на поле. Кроме того, всплывающее окно можно было закрыть, кликнув вне окна или выбрав дату.
Элемент выбора даты
Большинство реализаций логики кликов вне окна выполнены с использованием реальных обработчиков на событие клика, привязанных к модели DOM. Однако я хотел сделать наш элемент выбора даты более удобным, чтобы у вас была возможность открывать календарь с помощью вкладок и также его закрывать. К тому же, обработчики могут конфликтовать друг с другом, если у вас на странице будет несколько элементов выбора даты.
А что, если сделать акцент на встроенный фокус ввода и событие потери фокуса элементом управления вместо кликов вне окна? Они, конечно, поддерживают вкладки, события касания и клика и уже реализованы в браузере. Единственная проблема, которую в данном случае необходимо решить, - когда вы нажимаете на всплывающее окно, но не выбираете дату, фокус смещается на календарь, вызывает событие потери фокуса при вводе текста и всплывающее окно закрывается.
И вот тут я задумался о том, есть ли способ кликнуть, но при этом не смещать фокус. Немного покопавшись в Гугл, я нашел способ сделать так: блокировать действие по умолчанию события
mouseDown
для всплывающего окна. Вот так просто в одну строку – все клики срабатывают, но фокус остается на поле ввода текста.
Казалось бы, решение найдено, двигаемся дальше, но что-то внутри останавливало меня. Почему именно
mouseDown
, а не
mouseUp
блокирует фокус, и при этом распространяет событие клика? Можно ли назвать это рабочим проектом стандарта? Можно ли доверять этому решению? Является ли оно кроссбраузерным? К тому же библиотека тестирования React, которую мы использовали для интеграционных тестов, не поддерживала такое решение, и мне пришлось бы изменить имитационную функцию.
Что такое сетевые стандарты?
Ладно, раз ответа Stack Overflow мне было недостаточно, что же тогда может быть лучше сетевых стандартов для того, чтобы изучить поведение браузера?
Вы, скорее всего, слышали о W3C или World Wide Web Consortium (Консорциум Всемирной паутины). Это международное сообщество, которое разрабатывает открытые стандарты для Интернета. W3C следит за тем, чтобы все придерживались одних и тех де рекомендаций, вследствие чего пропадет необходимость поддерживать десятки совершенно разных сред. Если вы зайдете на их сайт, то вы найдете там список всех стандартов, над которыми они работают.
Давайте посмотрим на один документ, который может ответить на ваши вопросы - UI Events Standard (Стандарт событий пользовательского интерфейса). Этот документ устанавливает поток событий DOM, определяет список событий и порядок их выполнения. Если вы думаете, что стандарты – это скучный, непонятный и сложный текст, то переходите сразу к разделу «DOM Event Architecture» («Архитектура событий DOM»), в котором рассказывается о всплывании и погружении событий с помощью красивых картинок, но все же они достаточно специфичны, какими и должны быть стандарты. Вы удивитесь качеству документа, он действительно хорошо написан, и в нем приведено огромное количество примеров и рекомендаций.
В нем даже есть определение нашего события
mouseDown
и его действий по умолчанию:
«Во многих реализациях для запуска различных действий по умолчанию, которые зависят от контекста, используется событие
mouseDown
. Вы можете помешать этим действиям выполниться, если отмените это событие. Некоторые из действий по умолчанию могут включать в себя: начало взаимодействия с помощью перетаскивания изображения или ссылки, начало выделения текста и т.д. К тому же, в некоторых реализациях есть функция горизонтальной прокрутки с помощью мыши, которая активируется при нажатии средней кнопки мыши в момент отправки события
mouseDown
.»
Итак, у нашего события есть некоторые действия по умолчанию, но нет никакой конкретной информации о фокусе, а все потому, что это на самом деле зависит от реализации браузера. Давайте посмотрим.
Введение в браузерные движки
Современный браузер – это достаточно мудрёное программное обеспечение с кодовой базой, которая состоит из десятка миллионов строк кода. И потому его, как правило, разбивают на несколько частей.
Для того, чтобы найти место, где определяются события фокуса, нам нужно выяснить, за что отвечает каждая из частей. Давайте начнем с Chromium и его проектной документации «Getting Around The Chrome Source Code» («Знакомство с исходным кодом Chrome»). Как мы можете видеть, здесь очень много различных модулей, которые отвечают за различную логику.
Общий обзор на Chromium
Давайте кратко пройдемся по ним, чтобы понять, как они все вместе работают:
оболочка пользовательского интерфейса (chrome)
: это базовое приложение, в котором содержится логика запуска, пользовательский интерфейс и все окна. Оно содержит проекты для
chrome.exe
и
chrome.dll
. Также здесь можно найти вспомогательные средства, такие как иконки и курсоры.
наполнение (content)
: это серверная часть приложения, которая обеспечивает связь с дочерними процессами.
net
: это библиотека для взаимодействия в сети, она помогает делать запросы к веб-сайтам.
основа (base)
: место расположения общего кода, который используют все подпроекты. В него могут входить такие вещи, как работа со строками, универсальные утилиты и т.д.
blink
: это механизм визуализации, который отвечает за весь конвейер визуализации, включая DOM-деревья, стили, события, интеграцию с V8.
V8
: последняя большая часть браузера – движок JavaScript. Его задача – компилировать JavaScript в собственный машинный код.
Как вы можете видеть, браузер состоит из нескольких независимых частей, которые взаимодействуют друг с другом через API. Самый большой интерес для разработчиков представляю Blink и V8. Действия по умолчанию, которые определены браузером, не являются частью V8, но при этом они все должны быть определены и реализованы в Blink. Однако перед тем, как мы перейдем к рассмотрению кодовой базы Blink, давайте разберем, как работают браузеры с точки зрения пользователя.
Конвейер визуализации
Представьте, что вы вводите адрес домена в браузере, после чего он выбирает и загружает какое-то количество ресурсов: файлы HTML, CSS и JS, изображения, иконки. Но что происходит дальше?
Конвейер визуализации веб-браузера
На первом этапе HTML-файлы будут проанализированы с точки зрения синтаксиса и преобразованы в
DOM-дерево
. DOM – это не только внутреннее представление страницы, но и API, который предоставляется JavaScript для запрашивания и изменения визуализации через систему, которая называется «привязками».
После того, как DOM-дерево будет сформировано, следующий шаг - обработка стилей CSS. Для этой цели в браузерах есть синтаксический анализатор CSS, который создает модель правил стиля. Создав модель правил стиля, мы можем объединить ее с набором стилей по умолчанию, которые есть в браузере, и вычислить конечное значение каждого свойства стиля для каждого элемента модели DOM. Такой процесс называется
разбиением стилей (или перерасчетом стилей)
.
В следующей части построения
макета страницы
мы должны определить наглядную геометрию всех элементов. На данном этапе каждому элементу присваиваются свои координаты (х и у), ширина и высота. Механизм визуализации вычисляет и фиксирует все области переполнения – какие элементы видны, а какие нет.
Как только мы получили координаты всех элементов, мы можем приступить к
расцвечиванию
. Для этого нам потребуются координаты, полученные на предыдущем этапе, и цвет из правил стиля. Мы объединяем их в список команд для расцвечивания. Важно расцвечивать элементы в правильном порядке, чтобы они правильно наслаивались. Порядок можно изменить с помощью правила стиля
z-index
.
Давайте выполним наш список команд по расцвечиванию и преобразуем их в битовый массив значений цвета. Этот этап называется
созданием растрового изображения
. Здесь же мы берем наши изображения и аналогично декодируем их в битовый массив.
В дальнейшем растровое изображение будет храниться в памяти
графического процессора
. На этом этапе подключаются библиотеки, которые отделяют аппаратное обеспечение и выполняют вызовы OpenGL и DirectX в Windows. Когда графический процессор получает команды для отображения битового массива, он начинает рисовать пиксели на вашем экране.
На данный момент у нас есть самые важные части конвейера визуализации. Но что будет, если вы прокрутите страницу или если на ней будет какая-нибудь анимация? В принципе, визуализация не является статичной. Изменения отображаются с помощью
кадров анимации
. Каждый кадр – это полная визуализация состояния содержимого страницы в какой-то определенный момент времени. Реальной проблемой в данной ситуации является ее производительность. Анимация с плавным переходом между кадрами требует генерации хотя бы 60 кадров в секунду. Было бы практически невозможно пройти весь конвейер 60 раз за секунду, особенно на медленных устройствах.
А что, если вместо того, чтобы каждый раз заново визуализировать все, мы, сделаем так, что можно будет на каком-то определенном этапе
объявить
элемент
недействительным
. Например, если вы динамически измените цвет кнопки, то браузер отметит этот элемент как недействительный, и в следующем кадре анимации он будет перерисован. Если никаких изменений не было, то мы можем повторно использовать старый кадр.
Это отличный способ оптимизировать небольшие динамические изменения в содержимом страницы. А теперь давайте поразмышляем об изменениях в больших областях страницы. Например, при прокрутке страницы все пиксели должны поменяться. Для этого страницу разбивают на слои, которые будут переформировываться в растровое изображение независимо друг от друга. Слой может быть довольно небольшим и отображать только один DOM-узел. Далее эти слои объединяются в связку, называемую
потоком компоновщика
. Оптимизировав процесс таким образом, вам не нужно будет заново создавать растровое изображения для всего подряд, вы будете делать это для слоев небольшого размера, а затем правильно комбинировать их.
Мы уже поняли, что делает Blink и как выглядит конвейер визуализации. Давайте углубимся в код.
Навигация по кодовой базе Blink
Похоже, что мы уже на финишной прямой. Давайте откроем репозиторий Blink и посмотрим на него.
Корневая папка репозитория Blink
Несмотря на то, что мы значительно сузили наш первоначальный вопрос, найти вручную конкретную строку кода, которая отвечает за блокировку фокуса, будет трудно.
Давайте попробуем произвести поиск в Google по названию нашего события:
mousedown site:https://chromium.googlesource.com/chromium/blink/+/master/Source
Поиск проводит нас к файлу
EventHandler
, где вы можете найти детали реализации многих входных событий. В частности, и самую важную для нас строчку:
bool swallowEvent = !dispatchMouseEvent(EventTypeNames::mousedown, mev.innerNode(), m_clickCount, mouseEvent);
Событие
dispatchMouseEvent
возвращает значение, которое означает «продолжить обработку по умолчанию», поэтому в случае использования
preventDefault
событие
swallowEvent
будет принимать значение
true
.
А чуть ниже вызывается событие фокуса, но оно срабатывает только, если
swallowEvent == false
.
swallowEvent = swallowEvent || handleMouseFocus(MouseEventWithHitTestResults(mouseEvent, hitTestResult), sourceCapabilities);
Вы можете изучить все действия по умолчанию для события нажатия мыши, а не только обработку фокуса, в том числе выбор, перетаскивание и прокрутку. Также в нем реализованы событие отпускания кнопки мыши и событие двойного щелчка. В принципе, там есть все.
Gecko и WebKit
На данный момент мы уже потратили какое-то время на то, чтобы изучить исходный код браузеров, и довольно хорошо понимаем их структуру, так почему бы на не посмотреть на Firefox и Safari в целом. Браузерный движок Firefox называется Gecko, а для Safari – это WebKit.
У Gecko есть страница обзора для разработчиков, то есть вы сможете получить представление об основных концепциях. Действуя по аналогии с Chrome, вы можете найти скромный файл
EventStateManager
,который состоит всего из 6000 строк кода. В нем описаны действия и поведение событий по умолчанию. Ссылка приведет вас к конкретной строке, так что вам не придется искать ее по всему файлу.
WebKit – это браузерный движок от Apple, который используется в Safari и других продуктах Apple. Blink (Chrome) – это ответвление WebKit, поэтому у них много общего, так что найти реализацию событий в их версии файла EventHandler было не так сложно.
Теперь, когда мы убедились в том, что можем безопасно блокировать событие
mousedown
, я могу вернуться и внести изменения в элемент выбора даты.
Заключение
Вместе мы прошли путь от простой задачи до введения в сетевые стандарты и деталей реализации браузера.
Не стоит бояться скрытой сложности используемых модулей, даже если это браузер или компилятор. В итоге вы поймете, что это был увлекательный путь. Есть шансы, что вы с легкостью найдете то, что можно улучшить, и, что не менее важно, получите уникальное понимание того, как все на самом деле работает. Я узнал много нового в процессе углубления в тему и хочу убедить вас сделать тоже самое. У браузеров есть отличная документация, и я уверен, что больше мне ничего не нужно.
