This document summarizes the architecture and design of Goozy, a social networking application built using Scala. Key points include:
1. Goozy uses the Scala programming language and is built around a RESTful API server with functionality for storage, background tasks, and email sending.
2. The application was originally developed using some features of the Lift web framework but encountered various issues related to performance, code style, and complexity.
3. The developers refactored to use the "cake pattern" which separates functionality into components with explicit dependencies to improve modularity, testability, and code quality.
A JavaScript function is a block of code designed to perform a particular task.
Why Functions?
You can reuse code: Define the code once, and use it many times. You can use the same code many times with different arguments, to produce different results.
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...Edureka!
( ** Full Stack Web Development Training: https://www.edureka.co/masters-program/full-stack-developer-training ** )
This Edureka tutorial on JavaScript explains all the fundamentals of JavaScript with examples. It also explains various features and applications of JavaScript. Following are the topics included in this tutorial:
1. What Is JavaScript?
2. Why Use JavaScript
3. JavaScript Fundamentals
- Data Types
- Variables
- Constants
- Loops
- Conditional Statements
- Functions
Generally speaking, a function is a "subprogram" that can be called by code external (or internal in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function, and the function will return a value.
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
A JavaScript function is a block of code designed to perform a particular task.
Why Functions?
You can reuse code: Define the code once, and use it many times. You can use the same code many times with different arguments, to produce different results.
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...Edureka!
( ** Full Stack Web Development Training: https://www.edureka.co/masters-program/full-stack-developer-training ** )
This Edureka tutorial on JavaScript explains all the fundamentals of JavaScript with examples. It also explains various features and applications of JavaScript. Following are the topics included in this tutorial:
1. What Is JavaScript?
2. Why Use JavaScript
3. JavaScript Fundamentals
- Data Types
- Variables
- Constants
- Loops
- Conditional Statements
- Functions
Generally speaking, a function is a "subprogram" that can be called by code external (or internal in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function, and the function will return a value.
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
JavaScript Arithmetic Operators
Arithmetic operators are used to perform arithmetic between variables and/or values.
JavaScript Assignment Operators
Assignment operators are used to assign values to JavaScript variables.
JavaScript String Operators
The + operator, and the += operator can also be used to concatenate (add) strings.
Comparison Operators
Comparison operators are used in logical statements to determine equality or difference between variables or values.
Conditional (Ternary) Operator
The conditional operator assigns a value to a variable based on a condition.
Logical Operators
Logical operators are used to determine the logic between variables or values.
JavaScript Bitwise Operators
Bit operators work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number. The result is converted back to a JavaScript number.
The delete Operator
The delete operator deletes a property from an object:
JavaScript - Chapter 9 - TypeConversion and Regular Expressions WebStackAcademy
Type Conversion:
JavaScript is loosely typed language and most of the time operators automatically convert a value to the right type but there are also cases when we need to explicitly do type conversions.
While JavaScript provides numerous ways to convert data from one type to another but there are two most common data conversions :
Converting Values to String
Converting Values to Numbers
Regular Expressions:
A regular expression is an object that describes a pattern of characters.
The JavaScript RegExp class represents regular expressions, and both String and RegExp define methods that use regular expressions to perform powerful pattern-matching and search-and-replace functions on text.
AJAX is an acronym standing for Asynchronous JavaScript and XML and this technology helps us to load data from the server without a browser page refresh.
If you are new with AJAX, I would recommend you go through our Ajax Tutorial before proceeding further.
JQuery is a great tool which provides a rich set of AJAX methods to develop next generation web application.
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
We rarely dive into current programming languages, touting the next new framework or the new features that will be out next year. This is about JavaScript the language as it exists today, what I picked up in going from C# to JS, and what C# picked up from JS along the way as well. It is based on Douglas Crockford's seminal book "JavaScript: The Good Parts".
JavaScript - An Introduction is a beginner's guide to JavaScript. It starts with very basic level and goes to intermediate level. You'll be introduced with every language constructs, Event handling, Form handling and AJAX which is supported by JavaScript with XMLHttpRequest object. This XHR object is discussed in enough detail so that you can understand how the underlying AJAX functionality works in jQuery. At the end it discusses advance concepts and library build on/around JavaScript.
In JavaScript, almost "everything" is an object.
-Booleans can be objects (if defined with the new keyword)
-Numbers can be objects (if defined with the new keyword)
-Strings can be objects (if defined with the new keyword)
-Dates are always objects
-Maths are always objects
-Regular expressions are always objects
-Arrays are always objects
-Functions are always objects
-Objects are always objects
From object oriented to functional domain modelingCodemotion
"From object oriented to functional domain modeling" by Mario Fusco
Malgrado l'introduzione delle lambda, la gran parte degli sviluppatori Java non è ancora abituata agli idiomi della programmazione funzionale e quindi non è pronta a sfruttare a pieno le potenzialità di Java 8. In particolare non è ancora comune vedere dati e funzioni usate insieme quando si modella un dominio di business. Lo scopo del talk è mostrare come alcuni principi di programmazione funzionale quali l'impiego di oggetti e strutture dati immutabili, l'uso di funzioni senza side-effect e il loro reuso mediante composizione, possono anche essere validi strumenti di domain modelling.
JavaScript Arithmetic Operators
Arithmetic operators are used to perform arithmetic between variables and/or values.
JavaScript Assignment Operators
Assignment operators are used to assign values to JavaScript variables.
JavaScript String Operators
The + operator, and the += operator can also be used to concatenate (add) strings.
Comparison Operators
Comparison operators are used in logical statements to determine equality or difference between variables or values.
Conditional (Ternary) Operator
The conditional operator assigns a value to a variable based on a condition.
Logical Operators
Logical operators are used to determine the logic between variables or values.
JavaScript Bitwise Operators
Bit operators work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number. The result is converted back to a JavaScript number.
The delete Operator
The delete operator deletes a property from an object:
JavaScript - Chapter 9 - TypeConversion and Regular Expressions WebStackAcademy
Type Conversion:
JavaScript is loosely typed language and most of the time operators automatically convert a value to the right type but there are also cases when we need to explicitly do type conversions.
While JavaScript provides numerous ways to convert data from one type to another but there are two most common data conversions :
Converting Values to String
Converting Values to Numbers
Regular Expressions:
A regular expression is an object that describes a pattern of characters.
The JavaScript RegExp class represents regular expressions, and both String and RegExp define methods that use regular expressions to perform powerful pattern-matching and search-and-replace functions on text.
AJAX is an acronym standing for Asynchronous JavaScript and XML and this technology helps us to load data from the server without a browser page refresh.
If you are new with AJAX, I would recommend you go through our Ajax Tutorial before proceeding further.
JQuery is a great tool which provides a rich set of AJAX methods to develop next generation web application.
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
We rarely dive into current programming languages, touting the next new framework or the new features that will be out next year. This is about JavaScript the language as it exists today, what I picked up in going from C# to JS, and what C# picked up from JS along the way as well. It is based on Douglas Crockford's seminal book "JavaScript: The Good Parts".
JavaScript - An Introduction is a beginner's guide to JavaScript. It starts with very basic level and goes to intermediate level. You'll be introduced with every language constructs, Event handling, Form handling and AJAX which is supported by JavaScript with XMLHttpRequest object. This XHR object is discussed in enough detail so that you can understand how the underlying AJAX functionality works in jQuery. At the end it discusses advance concepts and library build on/around JavaScript.
In JavaScript, almost "everything" is an object.
-Booleans can be objects (if defined with the new keyword)
-Numbers can be objects (if defined with the new keyword)
-Strings can be objects (if defined with the new keyword)
-Dates are always objects
-Maths are always objects
-Regular expressions are always objects
-Arrays are always objects
-Functions are always objects
-Objects are always objects
From object oriented to functional domain modelingCodemotion
"From object oriented to functional domain modeling" by Mario Fusco
Malgrado l'introduzione delle lambda, la gran parte degli sviluppatori Java non è ancora abituata agli idiomi della programmazione funzionale e quindi non è pronta a sfruttare a pieno le potenzialità di Java 8. In particolare non è ancora comune vedere dati e funzioni usate insieme quando si modella un dominio di business. Lo scopo del talk è mostrare come alcuni principi di programmazione funzionale quali l'impiego di oggetti e strutture dati immutabili, l'uso di funzioni senza side-effect e il loro reuso mediante composizione, possono anche essere validi strumenti di domain modelling.
Javascript and first-class citizenry: require.js & node.js
Javascript on web pages is ubiquitous and its problems are legendary. Javascript, seen as a second-class code citizen, is usually hacked together even by seasoned developers. New libraries (jQuery, prototype, backbone, knockout, underscore) and runtime tools (firebug, jasmine) look like they solve many problems - and they do. But they still leave poorly written code as just that. One key problem is that all javascript code lives globally and this results in poorly managed, tested and delivered code.
In this session, I will illustrate that we can treat javascript as a first-class citizen using with require.js and node.js: it can be modular, encapsulated and easily unit tested and added to continuous integration cycle. The dependencies between javascript modules can also be managed and packaged just like in C# and Java. In the end, we can resolve many javascript difficulties at compile time rather than waiting until runtime.
HTML5 is still evolving and, naturally, APEX cannot yet support all the new functionality declaratively. This doesn’t mean you cannot use new advanced HTML5 features and API’s in your application. In my session, I will explain and demonstrate 5 HTML5 functionalities that can add valuable functionality to your APEX application and how to (easily) integrate them in APEX.
In this session I will explain and demonstrate 5 HTML5 elements and API’s and how to integrate those in an Oracle Application Express application. The selected features are not declaratively supported by Application Express (yet) but can add functionality that improves functionality and user experience.
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
The field of Information retrieval (IR) is currently undergoing a transformative shift, at least partly due to the emerging applications of generative AI to information access. In this talk, we will deliberate on the sociotechnical implications of generative AI for information access. We will argue that there is both a critical necessity and an exciting opportunity for the IR community to re-center our research agendas on societal needs while dismantling the artificial separation between the work on fairness, accountability, transparency, and ethics in IR and the rest of IR research. Instead of adopting a reactionary strategy of trying to mitigate potential social harms from emerging technologies, the community should aim to proactively set the research agenda for the kinds of systems we should build inspired by diverse explicitly stated sociotechnical imaginaries. The sociotechnical imaginaries that underpin the design and development of information access technologies needs to be explicitly articulated, and we need to develop theories of change in context of these diverse perspectives. Our guiding future imaginaries must be informed by other academic fields, such as democratic theory and critical theory, and should be co-developed with social science scholars, legal scholars, civil rights and social justice activists, and artists, among others.
PHP Frameworks: I want to break free (IPC Berlin 2024)Ralf Eggert
In this presentation, we examine the challenges and limitations of relying too heavily on PHP frameworks in web development. We discuss the history of PHP and its frameworks to understand how this dependence has evolved. The focus will be on providing concrete tips and strategies to reduce reliance on these frameworks, based on real-world examples and practical considerations. The goal is to equip developers with the skills and knowledge to create more flexible and future-proof web applications. We'll explore the importance of maintaining autonomy in a rapidly changing tech landscape and how to make informed decisions in PHP development.
This talk is aimed at encouraging a more independent approach to using PHP frameworks, moving towards a more flexible and future-proof approach to PHP development.
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
I have heard many times that architecture is not important for the front-end. Also, many times I have seen how developers implement features on the front-end just following the standard rules for a framework and think that this is enough to successfully launch the project, and then the project fails. How to prevent this and what approach to choose? I have launched dozens of complex projects and during the talk we will analyze which approaches have worked for me and which have not.
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Let's dive deeper into the world of ODC! Ricardo Alves (OutSystems) will join us to tell all about the new Data Fabric. After that, Sezen de Bruijn (OutSystems) will get into the details on how to best design a sturdy architecture within ODC.
Данном докладе я расскажу о нашем с Юрой опыте использования Scala в живом проекте. Я не буду пытаться давать обзоры использованных технологий, в место этого доклад будет сконцентрирован на встреченных и найденных решениях.
Мой доклад будет проходить по следующему плану: 1. Сначала я кратко расскажу о сервисе который мы собственно разрабатываем. 2. Потом я рассмотрю место которое занимает Scala, точнее написанные на ней компоненты в проекте. И расскажу почему именно она была выбрана для их реализации. 3. Далее расскажу о том как в проекте используется известный фреймворк lift. 4. В четвёртой части я дам обзор логического устройства и того как на его становление повлиял широко разрекламированный cake pattern. 5. В пятой части будет рассказано про использовани библиотеки Scalaz в проекте. Закончу я тем, что расскажу про основные усвоенные из этого проекта уроки.
Итак, наш проект Goozy - социальная сеть, построенная вокруг концепции стикеров дял интернет-страниц. Основаня идея в том, что пользователь может оставлять в сети заметки с помощью браузерных плагинов и делиться имим со своими друзьями. Тут важно заметить, что помимо собственно оставления и просмотра стикера центральной концепцией интерфейса сервиса является так называемая "лента" - поток стикеров и комментариев от друзей данного пользователя. Проект уже достаточно пожилой и пережил несколько итераций разработки. Текущая итерация началась зимой с амбициозной целью построения бэкэнда для этого сервиса, способного обслуживать до миллиона активных пользователей. Современная архитектура проета выглядит так:...
Хранение данных доверено популярной ныне MongoDB. Это документоориентированаая БД, со встроенной поддержкой шардинга и репликации. Непосредственно с ней общаются так анзываемые сервера API. Они экспортируют REST интервейсы доступа к данным. Кроме того они отвечают за взаимодействие с внешними сервисами, такими как S3 и системы полнотекстового поиска. Несколько серверов подключаются к балансировщику нагрузки. К нему же подключаютс сервера с развернутым порталом проекта. Портал не общается напряму с БД и делегирует большинство взаимодействий с внешними сервисами API. Во внешний мир смотрит специально настроенный интерфейс балансера, открывающий доступ к порталу и предназначенным для этого методам API. Клиентские приложения прозрачно общаются с API и порталом по протоколу HTTP.
Основные функции, которые он на себя берёт это: 1. Управление доступом к хранилищам данных. 2. Выполнение части задач обработки данных в фоне. 3. Отсылка писем. 4. Направление необходимых данных в текстовые индексы. Тут встаёт вопрос: почему же для его реализации был выбран язык Scala? У меня есть следующие ответы...
Во-первых программы на нём быстры. Плохой алгоритм он не выправит, но написанный хорошо скорее всего будет работать со скоростью не очень далёкой от максимальной. Во-вторых он краток. Он не выедает время на ввод текста и поиск по нему. Более менее целостный компонент приложения обычно умещается на одном экране. Это очень положительно влияет на скорость работы. Он выразиетен. Если на нём нужно что-то сказать можно взять и сказать именно это. С ним нужда в ритуалах, не связанных с решаемой проблемой, минимальна. В есть целый ряд инструментов отсутствующих в других ОО-языках. Многие из них радикально упрощают решение архитектурных проблем. В первую очередь это traits (Кстати где-то видел их перевод как "типажи". Кто-нибудь им пользуется?). Кроме того более глубокая поддержка обобщённых типов положительно влияет ан стандартную библиотеку и соответственно почти на весь код. В ней есть развитая поддержка функционального программирования. В первую очередь это простая работа с константами. Как следствие значительно проще, чем в Java пистаь корректный многопоточный код. Ну и наконец нам доступен весь огромный арсенах библиотек, написанных на Java. Прежде чем углубиться в технические моменты пара слов о том, что вызывает наибольшие страхи перед переходом на Scala. Это люди, которые ан ней должны писать...
Итак, команда наша состояла из 2 человек. Все имели заметный опыт работы с Java в самых разнообразных направлениях. Ну и что важно все фанаты своего дела и любят новые технологические игрушки. Как следствие вопросы вроде разобраться с новой штукой или продраться через трёхэтажную ругань компилятора на несходящиеся типы никогда не превращались в проблемы. Теперь можно переходить и к технической стороне вопроса. Первое о чём хочется рассказать - это опыт применения Lift'а для создания REST-сервиса.
В связи с узостью решаемой задачи из всего огромного вреймворка импользуется буквально два модуля. Это поддержка REST сервисов и автоматическая сериализация case классов в JSON. Несмотря на скромность используемого функционала мы натолкнулись на несколько проблем.
Две связаны с производительностью и одна эстетического плана. Во первых мы столкнулись с очень низкой производительностью встроенного механизма интернационализации. Большие критические секции в его коде привели к тому, что на топовом EC2 инстансе мы могли обрабатывать порядка 20 запросов в секунду. Надо сказать, что это был очень грустный момент. Крутая модная БД, быстрый язык, ооочень много ядер и 20 запросов :( Но проблема нашлась быстро, код был переведён на на стандартные ResourceBundles, что увиличило пропускную способность в 4 раза. Вторая проблема выявленная, но не решённая - это потребление памяти при сериализации в JSON. Если не вдаваться в детали, то одни и те-же данные там переупаковываются 3 раза,, что накладывает определённые ограничения на производительность... Ну и последнее это сложный исходный код самого Lift. Местами просто сборник худших стереотипов о Scala. На этапе освоения невозможность быстро читать исходный код сильно тормозила разработку.
Теперь давайте немного рассмотрим архитектуру нашего API сервера. Логически она разнесена на честные (кстати впервые в моей практике) три уровня. Контролер - это код непосредственно связанный с лифтом и осуществляющий преобразование данных из HTTP во внутренние модели данных и обратно. Сервисы это фасады для операций, реализуемых сервером. Ещё целостные в терминах API (одна экспортируемая наружу операция - один метод), но уже оперирующие внутренними моделями данных. Внутри себя они координируют работу нескольких служб более низкого уровня, таких как рассылка почты,текстовый поиск, взаимодействие с внешними сервисами. Сложные операции с данными делегируются третьему уровню. Он отвечает за сохранение моделей данных в БД и их загрузку оттуда. Каждый уровень состоит из нескольких компонентов, образованных операциями над близкими классами моделей: пользователями, стикерами, лентой и т.д. Обеспечение поддерживаемости всего этого хозяйства имеет определённые трудности...
Во-первых компоненты каждого уровня обычно зависят друг от друга. Скажем загрузка объекта стикера требует загрузки объекта пользователя, который его оставил и т.п. Вторая проблема сотоит в том, и от предыдущего уровня компоненты имеют несколько зависимостей. Кроме того внутри одного уровня обычно имеется большое количество разделяемых данных и объектов. Например сконфигурированный пул соединений с БД или сервисом поиска.
Решение этих труднойстей мы попробовали найти в популярном в сообществе cake pattern. (Уточнить нужны ли пояснения) Я попробую сформулировать основные результаты этого решения...
Из положительного мы имеем: 1. Архитектура приложения выражена непосредственно в коде объёмом около 100 строк. Имеется в виду собственно конструирование рантайм компонентом и описанием всех зависимостей между ними. 2. Корректность описания зависимостей проверяется компилятором. 3. Сами компоненты получились сравнительно компактными. Размер отдельных классов в основном не превышает 100 строк. Основные проблемы которые при этом наблюдаются: 1. Длинные (иногда очень длинные) списки зависимостей у отдельных компонентов. Видимо это проблема нашего дизайна, но при использовании например Spring её можно спрятать подальше. 2. Неявная зависимость от порядка перечисления примесей в описании рантайм конфигурации. Случайное изменение этого порядка рефакторинг связанный с переносом функционала между компонентами часто видёт к падению приложения при старте. К счастью этот класс ошибок гарантированно отлавливается простейшим тестом. 3. Не понятно что делать, если у нас есть несколько одинаковых по типу зависимостей, которые однако должны иметь разные имплементации в рантайме. Например у нас есть две очереди сообщений и компонент должен уметь обращаться к обоим. Создание отдельного класса для каждого назначения одного и того же интерфейса не кажется хорошей идеей. Теперь пора рассказать про нашу любимую игрушку в проекте:
Одной из проблем вставшей на ранней стадии разработки проекта был корректные ответы клиенту при ошибках. То есть ответ должен был содержать краткое её описание, например "входной параметр вне допустимого диапазона" и правильный http-код. Естественно если у нас обнаруживалось несколько проблем доложить хотелось обо всех, что крайне осложняло использование исключений для этой цели. В то время я как раз наткнулся на пост известного скала-блоггера Дебашиша Гоша. И однажды я бросил Юре ссылку на блогпост с описанием обработки ошибок с помощью апликативных функторов. День спокойно проработал над какой-то фичёй, а уже следующим утром при обновлении и общего репозитария получил код из того поста...
Как собственно осуществлялся переход. В начале у нас был набор наших исключений которые при случае выбрасывались. И некоторые из них преобразовывались в ответы клиенту. Выглядели они так.
Собственно первым шагом для использования валидаций всегда должно становится определение типа ошибки. Так как конечной целью всей этой затеи было отправлять корректные ответы по http, то были созданы вот такие вот классы (их естественно было много больше) которые несли в себе данные об ошибке и нужный http-код. Всё было хорошо мы начали использоать вот такие вот структуры для сообщений об ошибках в параметрах запросов. Потихоньку распространяли это вглубь, на логику работы с БД... Но тут до нас дошло
В JVM бывают исключения. Они бывают по разным причинам, именно их используют многие замечательные библиотеки вроде casbah. И оборачивать каждое обращение к ним в try/catch абсолютно нереально. Мало того, кода бросающего наши исключения уже было немало.
Для решения проблемы была выбрана следующая стратегия: определить функцию конвертер из всех исключений в наши ошибки. Написать небольшую бибилотеку которая упростила бы обращение к этой функции из нашего кода.
В первую очередь мы добавили ещё одну унверсальную ошибку. Полагая что непредвиденное и не имеющее соответствующего маппинга исключение - это наш косяк и его надо рапортавать 500 кодом.
Написали такой вот простой конвертер.
И маленький набор утилит. Свой алиас для валидаций с подставленным типом ошибки. Обратите внимание что это очень удобно делать в любом проекте, так как мы получаем kind с 1 параметром, что в силу особенностей scala радикально упрощает написание некоторых сигнатур. Посмотрите на пример использования sequence - 80% этого ужаса уходит если есть такой алиас. Здесь я использовал очень интересную и очень малоизвестную часть стандартной библиотеки scala.control.Exceptions. Она демонстрирует интересный подход к проблеме функциональной обработки исключений, советую посмотреть.
Ещё была написана куча утилит для безопасного парсинга разных типов данных, работы с mongo объектами и ещё чем-то... Я их сюда не вставлял, так как перед новым годом накатал изрядный текст не тему как их писать, они достаточно тривиальны.
Имея весть этот арсенал мы начали плавно двигать валидации глбже и глубже в наш код... Получилось вполне себе мило, была куча вот такого вот симпатичного кода. Хаскелисты должны прослезится...
Но в процессе появлялся и другой код...
Вот такой вот... Возможно причина его появления в моём низком мастерстве использования этого аппарата. Но мне кажется что это фундаментальная проблема: есть класс кода который значительно читабельнее в старой доброй императивной форме с исключениями.
Так это или нет, нов итоге сформировался такой подход. Нов итоге сформировался такой подход: там где это проще мы пользуемся исключениями. Но стараемся переходить на валидации как можно раньше (на более низких уровнях логики) для того чтобы высокоуровневая логика могла следовать букве ФП.
Итак, код, совершающий много всякого ввода-вывода из сображений производительности и читабельности живёт с исключениями. интерфейсные методы небезопасных компонентов заворачиваются в специальные обёртки. Они перехватывают исключения и преобразуют их по определённым правилам в ошибки валидации. Правила задаются в одном месте глобально для всего приложения. Кстати при этом использовался стандартный пакет control.exceptions. Уровень сервисов и контроллеры оперируют более менее надёжными значениями, однако и они не застрахованы от выброса исключений. Для того чтобы обеспечить надёжную обработки и репортинг об ошибках не уровне лифта встроен дополнительный обработчик исключений, который делегирует всё к тому-же методу преобразования. На переходе между контроллерами и лифтом встроен код, который знает как из ошибок строить корректные с точки зрения HTTP ответы. В общем данная схема показала свою работоспособность. И более того устойчивость к отдельным нарушениям описанных соглашений (в том смысле, что отчёты об ошибках становятся менее точны, но не сводятся к метаю в пользователя стэктрейсами).
Итак, каков наш опыт использования валидаций. Во-первых положительные моменты: 1. Более менее понятный способ аггрегации ошибок валидации. 2. Мало того это практически единственный способ который может работать в условиях нескольких десятков параметров с 2-3 ограничениями на каждый. 3. Также нам удолась выстроить достаточно унифицированный подход к рапортам об ошибках как во входящих параметрах, так и об ошибках времени выполнения. 4. Ну и корректность обработки ошибок проверяется автоматически компилятором. Из проблемных моментов можно выделить: 1. Монады и функторы требуют долгой медитации, которая не проходит бесследно для сознания. 2. Иногда бывает сложно найти общий язык с компилятором. 3. Ну и наиболее сложная для преодоления проблема...