SlideShare a Scribd company logo
1 of 46
Download to read offline
SCALA,
FUNCTIONAL PROGRAMMING AND
TEAM PRODUCTIVITY
INTRO
WHO WE ARE
▸ Pavel and Kai
▸ Septimal Mind, an Irish consultancy
▸ Engineer’s productivity is our primary concern
▸ Love Scala and pure FP
▸ Scala contributors
INTRO
WHAT WE DO
▸ We identify productivity issues in SDLC pipeline
▸ We build tools to address these issues
▸ How do we decide to write a new tool?
▸ Prototype should take one engineer at most two weeks
CASE STUDY
CASE STUDY: STARTING POINT (JAN/2018)
▸ Millions of users, +100K each month
▸ About 30 engineers
▸ Back-end: About 10 microservices, multirepo
▸ Front-end: mobile apps, web portal
▸ Scala as Java+ (akka-http, guice), C#, Go, Typescript
CASE STUDY
CASE STUDY: OUTCOME (JUN/2019)
Development costs cut by 50%
(management estimation)
CASE STUDY
WHAT WAS WRONG?
Late problem detection

Actual integration postponed to production
INTRO
WHAT WAS WRONG
▸ A lot of issues discovered in production
▸ Bugs
▸ Component incompatibilities
▸ Frontend incompatibilities
▸ Not enough insights to debug after failure
▸ Hard to just observe the product: 13 repositories
▸ Hard to get people on board
ISSUES
WHAT WAS WRONG?
No Real Continuous Integration
CASE STUDY
CASE STUDY: WHAT WE DID
The problems mentioned are fundamental...
... but we made things better...
...for this particular company
CASE STUDY
CASE STUDY: WHAT WE DID
▸ Formal interfaces: own IDL/DML/RPC compiler
▸ Better insights & metrics: own effort-free structured logging
▸ Convenient monorepo, better GIT flow
▸ Code quality: pure FP and Bifunctor Tagless Final
▸ Asynchronous stacktraces for ZIO
▸ Fast and reliable tests (including integration ones)
▸ "Flexible Monolith", multi-tenant applications
▸ Proper Continuous Integration
▸ Simplified onboarding
CASE STUDY
CASE STUDY: WHAT WE DID
Issue Solution
Late problem detection Early Integration

(IDL, Cheap Simulations, Dual tests, Bifunctor IO, Pure FP, TF)
Complicated onboarding
Better Observability

(Monorepo, Integration Checks, Dual Tests)
Lack of insights
Effortless insights

(Structural Logging, Async Stacktraces)
Code sharing
Observability, No Local Publishing

(Monorepo, Unified Stack, Unified Framework)
ISSUES
CASE STUDY: WHAT WE DID
Let's focus on
Tests and Microservices
ISSUES
WHAT WAS WRONG WITH TESTS
▸ Speed
▸ 600 tests
▸ 20 minutes total
▸ 17 for component startup and shutdown
▸ Interference
▸ Can’t run tests in parallel
▸ Slow External Dependencies
▸ Hard to wire Dummies (Guice)
ISSUES
WHAT WAS WRONG WITH MICROSERVICES
▸ Hard to share & reuse the code
▸ One shared Dev Env, hard to replicate locally
▸ Up to 70% of developer's time spent for retries and startups
▸ Automated Deployments & Orchestration
▸ Hard
▸ Fast, correct startup & shutdown are important...
▸ ...but hard to implement manually (order, variability)
GOALS
GOALS
▸ Improve development workflows
▸ Improve deployment workflows
▸ Continuously Integrate microservice fleet
▸ Improve team collaboration
▸ Simplify onboarding
GOALS
GOALS
How?


— Automatically Reconfigurable Applications
GOALS
GOALS
Product := Build(Components, Goals)
AUTOMATIC 

APPLICATION
COMPOSITION
GOALS
GOALS
▸ Test Business Logic without external dependencies
▸ Test Business Logic with real external dependencies too
▸ Correctly share (memoize) heavy resources between tests
▸ Let a new developer checkout & test immediately
▸ Let front-end engineers run isolated dev envs quickly & easily
DISTAGE FRAMEWORK
DIStage Framework
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: THE MODEL
object ServiceDemo {
trait Repository[F[_, _]]
class DummyRepository[F[_, _]] extends Repository[F]
class ProdRepository[F[_, _]] extends Repository[F]
class Service[F[_, _]](c: Repository[F]) extends
Repository[F]
class App[F[_, _]](s: Service[F]) {
def run: F[Throwable, Unit] = ???
}
}
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: DEFINITIONS
def definition[F[_, _]: TagKK] = new ModuleDef {
make[App[F]]
make[Service[F]]
make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]]
make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
}
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: STARTING THE APP
Injector(Activation(Repo -> Prod))
.produceRunF(definition[zio.IO]) {
app: App[zio.IO] =>
app.run
}
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: THE IDEA
distage app

=

set of formulas

Product := Recipe(Materials, ...)

+

set of "root" products

Set(Roots, ...)

+

configuration rules

Activation
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE
▸ Like Guice and other DIs, distage
▸ turns application wiring code into a set of declarations
▸ automatically orders wiring actions
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE
But not just that
DISTAGE FRAMEWORK
AUTOMATIC CONFIGURATIONS
make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]]
make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
DISTAGE FRAMEWORK
AUTOMATIC CONFIGURATIONS
Injector(Activation(Repo -> Repo.Prod))
make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]]
make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
DISTAGE FRAMEWORK
AUTOMATIC CONFIGURATIONS
Injector(Activation(Repo -> Repo.Prod))
make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]]
make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
DISTAGE FRAMEWORK
RESOURCES
trait DIResource[F[_], Resource] {
def acquire: F[Resource]
def release(resource: Resource): F[Unit]
}
▸ Functional description of lifecycle
▸ Initialisation without mutable state
DISTAGE FRAMEWORK
RESOURCES
// library ...
class DbDriver[F[_]] {
def shutdown: F[Unit]
}
def connectToDb[F[_]: Sync]: DbDriver[F]
// …
class ProdRepository[F[_]](db: DbDriver[F]) extends Repository
// definition ...
make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
make[DbDriver[F]].fromResource(DIResource.make(connectToDb)(_.shutdown))
// ...
▸ Graceful shutdown is always guaranteed, even in case of an exception
▸ Docker Containers may be expressed as resources
▸ Embedded replacement for docker-compose
DISTAGE FRAMEWORK
INTEGRATION CHECKS
▸ Check if an external service is available
▸ Tests will be skipped if checks fail
▸ The app will not start if checks fail
▸ Integration checks run before all initialisation
DISTAGE FRAMEWORK
INTEGRATION CHECKS
class DbCheck extends IntegrationCheck {
def resourcesAvailable(): ResourceCheck = {
if (checkPort()) ResourceCheck.Success()
else ResourceCheck.ResourceUnavailable("Can't connect to DB", None)
}
private def checkPort(): Boolean = ???
}
▸ Check if an external service is available
▸ Tests will be skipped if checks fail
▸ The app will not start if checks fail
▸ Integration checks run before all initialisation
DISTAGE FRAMEWORK
DUAL TEST TACTIC
▸ Helps draft business logic quickly
▸ Enforces SOLID design
▸ Does not prevent integration tests
▸ Speeds up onboarding
DISTAGE FRAMEWORK
DUAL TEST TACTIC: CODE
abstract class ServiceTest extends DistageBIOEnvSpecScalatest[ZIO] {
"our service" should {
"do something" in {
service: Service[zio.IO] => for {
// ...
} yield ()
}
}
}
trait DummyEnv extends DistageBIOEnvSpecScalatest[ZIO] {
override def config: TestConfig = super.config.copy(
activation = Activation(Repo -> Dummy))
}
trait ProdEnv extends DistageBIOEnvSpecScalatest[ZIO] {
override def config: TestConfig = super.config.copy(
activation = Activation(Repo -> Prod))
}
final class ServiceProdTest extends ServiceTest with ProdEnv
final class ServiceDummyTest extends ServiceTest with DummyEnv
DISTAGE FRAMEWORK
MEMOIZATION
abstract class DistageTestExample extends DistageBIOEnvSpecScalatest[ZIO] {
override def config: TestConfig = {
super.config.copy(memoizationRoots = Set(DIKey.get[DbDriver[zio.IO]]))
}
"our service" should {
"do something" in {
repository: Repository[zio.IO] =>
//...
}
"and do something else" in {
repository: Repository[zio.IO] =>
//...
}
}
}
DISTAGE FRAMEWORK
MEMOIZATION
▸ DbDriver will be shared across all the tests
▸ Without any singletons
▸ With graceful shutdown
▸ With separate contexts for different configurations
DISTAGE FRAMEWORK
AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE
▸ verifies correctness ahead of time
▸ supports resources and lifecycle
▸ provides a way to define configurable apps
▸ can perform integration checks ahead of time
▸ can perform graceful shutdown automatically
▸ can share components between multiple tests & entrypoints
DISTAGE:
ROLES
AS MEANS OF
CONTINUOUS INTEGRATION
Yes, Integration
DISTAGE FRAMEWORK
ROLES
class UsersRole extends RoleService[zio.Task] {
override def start(params: RawEntrypointParams, args: Vector[String]): DIResource[zio.Task, Unit] =
DIResource.make(acquire = {
// initialisation
})(release = {
_ =>
// shutdown
})
}
object UsersRole extends RoleDescriptor {
override final val id = "users"
}
# java -jar myapp.jar -u repo:prod -u transport:prod :users :accounts
# java -jar myapp.jar -u repo:dummy -u transport:vm :users :accounts
DISTAGE FRAMEWORK
ROLES
▸ Multiple "microservices" per process
▸ More flexibility for deployments
▸ Simulations
DISTAGE FRAMEWORK
ROLES
▸ Dev environment simulation in one process
▸ Even with in-memory mocks!
▸ Not a replacement for the dev env, but nice addition.
▸ Imperfect simulations are great anyway!
▸ Model imperfectness can be granularly adjusted
REAL CI
CONTINUOUS INTEGRATION
▸ A Microservice Fleet is a Distributed Application
▸ And that application is The Product
▸ Microservices are just components of our Product
▸ We should integrate them continuously too!
▸ But it's hard to start and test a distributed application
REAL CI
DISTRIBUTED APPLICATION SIMULATIONS
▸ Several "microservices" (roles) in one process
▸ Dummies for every Integration Point
▸ Easy configuration
▸ Cheap product models for Continuous Integration
▸ There is no need to fail in production
➡
DISTAGE FRAMEWORK
ROLES AND TEAMS
▸ Multi-tenant applications do not require a Monorepo
▸ It's possible to have a repository per role
▸ Each role repository may define individual role launcher
▸ And there may be one or more launcher repositories
▸ Drawback: unified framework is required
Thank you!
distage example:
https://github.com/7mind/distage-example
Pavel:
https://twitter.com/shirshovp
Kai:
https://twitter.com/kai_nyasha

More Related Content

What's hot

Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFXHendrik Ebbers
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails AppsRabble .
 
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?Julian Robichaux
 
How to setup unit testing in Android Studio
How to setup unit testing in Android StudioHow to setup unit testing in Android Studio
How to setup unit testing in Android Studiotobiaspreuss
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New FeaturesAli BAKAN
 
Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01rhemsolutions
 
Efficient JavaScript Unit Testing, JavaOne China 2013
Efficient JavaScript Unit Testing, JavaOne China 2013Efficient JavaScript Unit Testing, JavaOne China 2013
Efficient JavaScript Unit Testing, JavaOne China 2013Hazem Saleh
 
[AnDevCon 2016] Mutation Testing for Android
[AnDevCon 2016] Mutation Testing for Android[AnDevCon 2016] Mutation Testing for Android
[AnDevCon 2016] Mutation Testing for AndroidHazem Saleh
 
Load Testing with k6 framework
Load Testing with k6 frameworkLoad Testing with k6 framework
Load Testing with k6 frameworkSvetlin Nakov
 
Unit Test Android Without Going Bald
Unit Test Android Without Going BaldUnit Test Android Without Going Bald
Unit Test Android Without Going BaldDavid Carver
 
Managed Beans: When, Why and How
Managed Beans: When, Why and HowManaged Beans: When, Why and How
Managed Beans: When, Why and HowRussell Maher
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02rhemsolutions
 
Testing Your Application On Google App Engine
Testing Your Application On Google App EngineTesting Your Application On Google App Engine
Testing Your Application On Google App EngineIndicThreads
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in YiiIlPeach
 
Devoxx17 - Préparez-vous à la modularité selon Java 9
Devoxx17 - Préparez-vous à la modularité selon Java 9Devoxx17 - Préparez-vous à la modularité selon Java 9
Devoxx17 - Préparez-vous à la modularité selon Java 9Alexis Hassler
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Appschrisb206 chrisb206
 
Супер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSСупер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSSQALab
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 

What's hot (20)

Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?
Connect2017 DEV-1550 Why Java 8? Or, What's a Lambda?
 
How to setup unit testing in Android Studio
How to setup unit testing in Android StudioHow to setup unit testing in Android Studio
How to setup unit testing in Android Studio
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New Features
 
Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01
 
Efficient JavaScript Unit Testing, JavaOne China 2013
Efficient JavaScript Unit Testing, JavaOne China 2013Efficient JavaScript Unit Testing, JavaOne China 2013
Efficient JavaScript Unit Testing, JavaOne China 2013
 
[AnDevCon 2016] Mutation Testing for Android
[AnDevCon 2016] Mutation Testing for Android[AnDevCon 2016] Mutation Testing for Android
[AnDevCon 2016] Mutation Testing for Android
 
Load Testing with k6 framework
Load Testing with k6 frameworkLoad Testing with k6 framework
Load Testing with k6 framework
 
Unit Test Android Without Going Bald
Unit Test Android Without Going BaldUnit Test Android Without Going Bald
Unit Test Android Without Going Bald
 
Managed Beans: When, Why and How
Managed Beans: When, Why and HowManaged Beans: When, Why and How
Managed Beans: When, Why and How
 
Unit testing - A&BP CC
Unit testing - A&BP CCUnit testing - A&BP CC
Unit testing - A&BP CC
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02
 
Testing Your Application On Google App Engine
Testing Your Application On Google App EngineTesting Your Application On Google App Engine
Testing Your Application On Google App Engine
 
Sling IDE Tooling
Sling IDE ToolingSling IDE Tooling
Sling IDE Tooling
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
 
Devoxx17 - Préparez-vous à la modularité selon Java 9
Devoxx17 - Préparez-vous à la modularité selon Java 9Devoxx17 - Préparez-vous à la modularité selon Java 9
Devoxx17 - Préparez-vous à la modularité selon Java 9
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
 
Супер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSСупер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOS
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 

Similar to Scala, Functional Programming and Team Productivity

Javaone - Gradle: Harder, Better, Stronger, Faster
Javaone - Gradle: Harder, Better, Stronger, Faster Javaone - Gradle: Harder, Better, Stronger, Faster
Javaone - Gradle: Harder, Better, Stronger, Faster Andres Almiray
 
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...VictorSzoltysek
 
Testing your application on Google App Engine
Testing your application on Google App EngineTesting your application on Google App Engine
Testing your application on Google App EngineInphina Technologies
 
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Christian Catalan
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Real world Webapp
Real world WebappReal world Webapp
Real world WebappThings Lab
 
Anatomy of a Build Pipeline
Anatomy of a Build PipelineAnatomy of a Build Pipeline
Anatomy of a Build PipelineSamuel Brown
 
AWS Webcast - Build Agile Applications in AWS Cloud for Government
AWS Webcast - Build Agile Applications in AWS Cloud for GovernmentAWS Webcast - Build Agile Applications in AWS Cloud for Government
AWS Webcast - Build Agile Applications in AWS Cloud for GovernmentAmazon Web Services
 
Microsoft SQL Server Testing Frameworks
Microsoft SQL Server Testing FrameworksMicrosoft SQL Server Testing Frameworks
Microsoft SQL Server Testing FrameworksMark Ginnebaugh
 
DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?Michael Elder
 
Spring Native and Spring AOT
Spring Native and Spring AOTSpring Native and Spring AOT
Spring Native and Spring AOTVMware Tanzu
 
Scala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouScala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouJ On The Beach
 
Make Your Build Great Again (DroidConSF 2017)
Make Your Build Great Again (DroidConSF 2017)Make Your Build Great Again (DroidConSF 2017)
Make Your Build Great Again (DroidConSF 2017)Jared Burrows
 
From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]Dynatrace
 
A Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy SystemA Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy Systemadrian_nye
 
Building JBoss AS 7 for Fedora
Building JBoss AS 7 for FedoraBuilding JBoss AS 7 for Fedora
Building JBoss AS 7 for Fedorawolfc71
 

Similar to Scala, Functional Programming and Team Productivity (20)

Javaone - Gradle: Harder, Better, Stronger, Faster
Javaone - Gradle: Harder, Better, Stronger, Faster Javaone - Gradle: Harder, Better, Stronger, Faster
Javaone - Gradle: Harder, Better, Stronger, Faster
 
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...
Real-World DevOps — 20 Practical Developers Tips for Tightening Your Operatio...
 
Testing your application on Google App Engine
Testing your application on Google App EngineTesting your application on Google App Engine
Testing your application on Google App Engine
 
Intro to DevOps
Intro to DevOpsIntro to DevOps
Intro to DevOps
 
React Native
React NativeReact Native
React Native
 
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Rajiv Profile
Rajiv ProfileRajiv Profile
Rajiv Profile
 
Real world Webapp
Real world WebappReal world Webapp
Real world Webapp
 
Anatomy of a Build Pipeline
Anatomy of a Build PipelineAnatomy of a Build Pipeline
Anatomy of a Build Pipeline
 
AWS Webcast - Build Agile Applications in AWS Cloud for Government
AWS Webcast - Build Agile Applications in AWS Cloud for GovernmentAWS Webcast - Build Agile Applications in AWS Cloud for Government
AWS Webcast - Build Agile Applications in AWS Cloud for Government
 
Microsoft SQL Server Testing Frameworks
Microsoft SQL Server Testing FrameworksMicrosoft SQL Server Testing Frameworks
Microsoft SQL Server Testing Frameworks
 
DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?
 
Spring Native and Spring AOT
Spring Native and Spring AOTSpring Native and Spring AOT
Spring Native and Spring AOT
 
Scala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouScala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camou
 
Pyramid deployment
Pyramid deploymentPyramid deployment
Pyramid deployment
 
Make Your Build Great Again (DroidConSF 2017)
Make Your Build Great Again (DroidConSF 2017)Make Your Build Great Again (DroidConSF 2017)
Make Your Build Great Again (DroidConSF 2017)
 
From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]
 
A Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy SystemA Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy System
 
Building JBoss AS 7 for Fedora
Building JBoss AS 7 for FedoraBuilding JBoss AS 7 for Fedora
Building JBoss AS 7 for Fedora
 

Recently uploaded

A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 

Recently uploaded (20)

A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 

Scala, Functional Programming and Team Productivity

  • 2. INTRO WHO WE ARE ▸ Pavel and Kai ▸ Septimal Mind, an Irish consultancy ▸ Engineer’s productivity is our primary concern ▸ Love Scala and pure FP ▸ Scala contributors
  • 3. INTRO WHAT WE DO ▸ We identify productivity issues in SDLC pipeline ▸ We build tools to address these issues ▸ How do we decide to write a new tool? ▸ Prototype should take one engineer at most two weeks
  • 4. CASE STUDY CASE STUDY: STARTING POINT (JAN/2018) ▸ Millions of users, +100K each month ▸ About 30 engineers ▸ Back-end: About 10 microservices, multirepo ▸ Front-end: mobile apps, web portal ▸ Scala as Java+ (akka-http, guice), C#, Go, Typescript
  • 5. CASE STUDY CASE STUDY: OUTCOME (JUN/2019) Development costs cut by 50% (management estimation)
  • 6. CASE STUDY WHAT WAS WRONG? Late problem detection
 Actual integration postponed to production
  • 7. INTRO WHAT WAS WRONG ▸ A lot of issues discovered in production ▸ Bugs ▸ Component incompatibilities ▸ Frontend incompatibilities ▸ Not enough insights to debug after failure ▸ Hard to just observe the product: 13 repositories ▸ Hard to get people on board
  • 8. ISSUES WHAT WAS WRONG? No Real Continuous Integration
  • 9. CASE STUDY CASE STUDY: WHAT WE DID The problems mentioned are fundamental... ... but we made things better... ...for this particular company
  • 10. CASE STUDY CASE STUDY: WHAT WE DID ▸ Formal interfaces: own IDL/DML/RPC compiler ▸ Better insights & metrics: own effort-free structured logging ▸ Convenient monorepo, better GIT flow ▸ Code quality: pure FP and Bifunctor Tagless Final ▸ Asynchronous stacktraces for ZIO ▸ Fast and reliable tests (including integration ones) ▸ "Flexible Monolith", multi-tenant applications ▸ Proper Continuous Integration ▸ Simplified onboarding
  • 11. CASE STUDY CASE STUDY: WHAT WE DID Issue Solution Late problem detection Early Integration
 (IDL, Cheap Simulations, Dual tests, Bifunctor IO, Pure FP, TF) Complicated onboarding Better Observability
 (Monorepo, Integration Checks, Dual Tests) Lack of insights Effortless insights
 (Structural Logging, Async Stacktraces) Code sharing Observability, No Local Publishing
 (Monorepo, Unified Stack, Unified Framework)
  • 12. ISSUES CASE STUDY: WHAT WE DID Let's focus on Tests and Microservices
  • 13. ISSUES WHAT WAS WRONG WITH TESTS ▸ Speed ▸ 600 tests ▸ 20 minutes total ▸ 17 for component startup and shutdown ▸ Interference ▸ Can’t run tests in parallel ▸ Slow External Dependencies ▸ Hard to wire Dummies (Guice)
  • 14. ISSUES WHAT WAS WRONG WITH MICROSERVICES ▸ Hard to share & reuse the code ▸ One shared Dev Env, hard to replicate locally ▸ Up to 70% of developer's time spent for retries and startups ▸ Automated Deployments & Orchestration ▸ Hard ▸ Fast, correct startup & shutdown are important... ▸ ...but hard to implement manually (order, variability)
  • 15. GOALS GOALS ▸ Improve development workflows ▸ Improve deployment workflows ▸ Continuously Integrate microservice fleet ▸ Improve team collaboration ▸ Simplify onboarding
  • 19. GOALS GOALS ▸ Test Business Logic without external dependencies ▸ Test Business Logic with real external dependencies too ▸ Correctly share (memoize) heavy resources between tests ▸ Let a new developer checkout & test immediately ▸ Let front-end engineers run isolated dev envs quickly & easily
  • 21. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: THE MODEL object ServiceDemo { trait Repository[F[_, _]] class DummyRepository[F[_, _]] extends Repository[F] class ProdRepository[F[_, _]] extends Repository[F] class Service[F[_, _]](c: Repository[F]) extends Repository[F] class App[F[_, _]](s: Service[F]) { def run: F[Throwable, Unit] = ??? } }
  • 22. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: DEFINITIONS def definition[F[_, _]: TagKK] = new ModuleDef { make[App[F]] make[Service[F]] make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]] make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]] }
  • 23. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: STARTING THE APP Injector(Activation(Repo -> Prod)) .produceRunF(definition[zio.IO]) { app: App[zio.IO] => app.run }
  • 24. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: THE IDEA distage app
 =
 set of formulas
 Product := Recipe(Materials, ...)
 +
 set of "root" products
 Set(Roots, ...)
 +
 configuration rules
 Activation
  • 25. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE ▸ Like Guice and other DIs, distage ▸ turns application wiring code into a set of declarations ▸ automatically orders wiring actions
  • 26. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE But not just that
  • 28. DISTAGE FRAMEWORK AUTOMATIC CONFIGURATIONS Injector(Activation(Repo -> Repo.Prod)) make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]] make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
  • 29. DISTAGE FRAMEWORK AUTOMATIC CONFIGURATIONS Injector(Activation(Repo -> Repo.Prod)) make[Repository[F]].tagged(Repo.Dummy).from[DummyRepository[F]] make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]]
  • 30. DISTAGE FRAMEWORK RESOURCES trait DIResource[F[_], Resource] { def acquire: F[Resource] def release(resource: Resource): F[Unit] } ▸ Functional description of lifecycle ▸ Initialisation without mutable state
  • 31. DISTAGE FRAMEWORK RESOURCES // library ... class DbDriver[F[_]] { def shutdown: F[Unit] } def connectToDb[F[_]: Sync]: DbDriver[F] // … class ProdRepository[F[_]](db: DbDriver[F]) extends Repository // definition ... make[Repository[F]].tagged(Repo.Prod).from[ProdRepository[F]] make[DbDriver[F]].fromResource(DIResource.make(connectToDb)(_.shutdown)) // ... ▸ Graceful shutdown is always guaranteed, even in case of an exception ▸ Docker Containers may be expressed as resources ▸ Embedded replacement for docker-compose
  • 32. DISTAGE FRAMEWORK INTEGRATION CHECKS ▸ Check if an external service is available ▸ Tests will be skipped if checks fail ▸ The app will not start if checks fail ▸ Integration checks run before all initialisation
  • 33. DISTAGE FRAMEWORK INTEGRATION CHECKS class DbCheck extends IntegrationCheck { def resourcesAvailable(): ResourceCheck = { if (checkPort()) ResourceCheck.Success() else ResourceCheck.ResourceUnavailable("Can't connect to DB", None) } private def checkPort(): Boolean = ??? } ▸ Check if an external service is available ▸ Tests will be skipped if checks fail ▸ The app will not start if checks fail ▸ Integration checks run before all initialisation
  • 34. DISTAGE FRAMEWORK DUAL TEST TACTIC ▸ Helps draft business logic quickly ▸ Enforces SOLID design ▸ Does not prevent integration tests ▸ Speeds up onboarding
  • 35. DISTAGE FRAMEWORK DUAL TEST TACTIC: CODE abstract class ServiceTest extends DistageBIOEnvSpecScalatest[ZIO] { "our service" should { "do something" in { service: Service[zio.IO] => for { // ... } yield () } } } trait DummyEnv extends DistageBIOEnvSpecScalatest[ZIO] { override def config: TestConfig = super.config.copy( activation = Activation(Repo -> Dummy)) } trait ProdEnv extends DistageBIOEnvSpecScalatest[ZIO] { override def config: TestConfig = super.config.copy( activation = Activation(Repo -> Prod)) } final class ServiceProdTest extends ServiceTest with ProdEnv final class ServiceDummyTest extends ServiceTest with DummyEnv
  • 36. DISTAGE FRAMEWORK MEMOIZATION abstract class DistageTestExample extends DistageBIOEnvSpecScalatest[ZIO] { override def config: TestConfig = { super.config.copy(memoizationRoots = Set(DIKey.get[DbDriver[zio.IO]])) } "our service" should { "do something" in { repository: Repository[zio.IO] => //... } "and do something else" in { repository: Repository[zio.IO] => //... } } }
  • 37. DISTAGE FRAMEWORK MEMOIZATION ▸ DbDriver will be shared across all the tests ▸ Without any singletons ▸ With graceful shutdown ▸ With separate contexts for different configurations
  • 38. DISTAGE FRAMEWORK AUTOMATED APPLICATION COMPOSITION: THE DIFFERENCE ▸ verifies correctness ahead of time ▸ supports resources and lifecycle ▸ provides a way to define configurable apps ▸ can perform integration checks ahead of time ▸ can perform graceful shutdown automatically ▸ can share components between multiple tests & entrypoints DISTAGE:
  • 39. ROLES AS MEANS OF CONTINUOUS INTEGRATION Yes, Integration
  • 40. DISTAGE FRAMEWORK ROLES class UsersRole extends RoleService[zio.Task] { override def start(params: RawEntrypointParams, args: Vector[String]): DIResource[zio.Task, Unit] = DIResource.make(acquire = { // initialisation })(release = { _ => // shutdown }) } object UsersRole extends RoleDescriptor { override final val id = "users" } # java -jar myapp.jar -u repo:prod -u transport:prod :users :accounts # java -jar myapp.jar -u repo:dummy -u transport:vm :users :accounts
  • 41. DISTAGE FRAMEWORK ROLES ▸ Multiple "microservices" per process ▸ More flexibility for deployments ▸ Simulations
  • 42. DISTAGE FRAMEWORK ROLES ▸ Dev environment simulation in one process ▸ Even with in-memory mocks! ▸ Not a replacement for the dev env, but nice addition. ▸ Imperfect simulations are great anyway! ▸ Model imperfectness can be granularly adjusted
  • 43. REAL CI CONTINUOUS INTEGRATION ▸ A Microservice Fleet is a Distributed Application ▸ And that application is The Product ▸ Microservices are just components of our Product ▸ We should integrate them continuously too! ▸ But it's hard to start and test a distributed application
  • 44. REAL CI DISTRIBUTED APPLICATION SIMULATIONS ▸ Several "microservices" (roles) in one process ▸ Dummies for every Integration Point ▸ Easy configuration ▸ Cheap product models for Continuous Integration ▸ There is no need to fail in production ➡
  • 45. DISTAGE FRAMEWORK ROLES AND TEAMS ▸ Multi-tenant applications do not require a Monorepo ▸ It's possible to have a repository per role ▸ Each role repository may define individual role launcher ▸ And there may be one or more launcher repositories ▸ Drawback: unified framework is required