Este documento describe las diferencias entre la programación síncrona y asíncrona, y cómo los paradigmas de programación orientada a objetos y funcional pueden usar técnicas avanzadas de programación asíncrona. Luego, presenta ejemplos prácticos de cómo implementar programación asíncrona en Java 8 y Kotlin, incluido un emulador de Gameboy que usa coroutinas de Kotlin para manejar la CPU de forma asíncrona.
3. 3
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Operaciones bloqueantes
• Ejecución secuencial
• Comportamiento por transformación de estados
• Devolución de resultados por finalización de estado
• Mezcla contextos Fronted/Backend
• Entorpece la escalabilidad
• Satura la CPU
• Poco performance
Motivación - Programación secuencial
4. 4
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Motivación - Programación secuencial
5. 5
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Motivación - Programación asíncrona
• Operaciones NO bloqueantes
• Ejecución NO secuencial
• Comportamiento diferido
• Devolución del resultado por suspensión
• Separa contextos Fronted (UI-Thread) / Backend (Threadn)
• Explotación de la CPU / GPU
• Alta escalabilidad
• Mejor performance
6. 6
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Motivación - Programación asíncrona
7. 7
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Motivación - Async Versus Sync
8. 88
Me presento ...
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Víctor M. Bolinches
Software Architect en Capgemini
Github Linkedin Twitter
vicboma1 victorbolinches @vicboma1
9. 9
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Introducción
• Conceptos básicos
• Programación Orientada a objetos
•Java 8, Kotlin y Javascript
•Ejemplos prácticos
• Programación Funcional
•Haskell y F#
• Referencias
11. 11
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Conceptos básicos
• Paradigma de programación
• Comunicación entre procesos
• Patrón promesa
• TDD
12. 12
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• OOP
• Estructura de datos llamados objetos
• Aglutinan propiedades y métodos
• Manipula datos de entrada para generar datos de salida
específicos
• FP
• Estructura mediante expresiones
• Variables sin estado e inmutables
• Recursión y Funciones de primer orden
• Definición de cómputos y cálculo de lambdas
Paradigmas de programación
14. 14
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Síncrono
• Intercambio de información en tiempo real
• Concurrente
• Ejecución simultánea de tareas en tiempo real
• Paralelo
• Sistema multi-procesado (Subdomino concurrente)
• Asíncrono
• Intercambio de información en tiempo diferido
Comunicación entre procesos
15. 15
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Comunicación entre procesos
16. 16
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Redirige flujos uniformes
• (A)síncronos
• Ordena y estructura bloques
• Resolve / Reject
• Flexibilidad de código
• Evita “Callbacks hell”
• Hacer p(), y luego q(), r() y s() → [ p ⇒ q ⇒ r ⇒ s ]
• Promise(p).then(q).then(r).then(s);
Patrón Promesa
17. 17
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Patrón Promesa
18. 18
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Iteraciones
• Desarrollo mediante pruebas ( Fallo – Acierto)
• Refactorizaciones
• Implementaciones mínimas necesarias
• Minimización del número de errores en producción
• Software modular, reutilizable y tolerable a cambios
Test-Driven Development
22. 22
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Package { java.utils.stream.* }
• Clase que soporta operaciones con estilo funcional
• Lambdas
• Interfaces funcionales
• Métodos y constructores por referencia
• Definición de métodos predeterminados y estáticos a interfaces
• Uso de “pipelines” (Patrón Builder)
Java 8 – Streams ← Ejemplos!!!
23. 23
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
/**Performs a reduction on the elements of this stream, using an associative
* accumulation function, and returns an Optional describing the reduced value, if any.
* @throws Exception
*/
@Test
public void reduce() throws Exception {
final int expected = 789;
final int result = Arrays.asList(18, 19, 29, 23, 43, 266, 789)
.parallelStream()
.reduce((p1, p2) -> p1 > p2 ? p1 : p2)
.get();
Assert.assertTrue(expected == result);
}
Java 8 – Streams { reduce }
38. 38
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | LoadAsync Rom
public static CompletableFuture<ByteBuffer> read(String filePath, int total) throws Exception {
final CompletableFuture<ByteBuffer> completableFuture = new CompletableFuture();
final AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get(filePath), StandardOpenOption.READ);
final ByteBuffer buffer = ByteBuffer.allocate(total);
channel.read(buffer, 0, null, new CompletionHandler<Integer, Void>() {
@Override public void completed(Integer result, Void attachment) {
try { channel.close(); } catch (IOException e) { e.printStackTrace(); }
buffer.flip();
completableFuture.complete(buffer);
}
@Override public void failed(Throwable exc, Void attachment) {
completableFuture.completeExceptionally(exc);
}
});
});
return completableFuture; }
39. 39
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Rendering
• Activo
• Pinta directamente en pantalla
• Gestión autónoma
• Manipulación a/síncrona
• Pasivo
• Atada a eventos
• Pintada por demanda del S.O.
• Diálogos modales
40. 40
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Técnicas de Pintado
Flashing Double Buffering
41. 41
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Técnicas de Pintado
• Double Buffering
• Block line transfer (btl)
• 1 buffer front + 1 buffer back
• Un solo puntero a memoria
• Crea la imagen y la copia en el screen en una sola operación
• Solución al parpadeo de imágenes (Flashing)
• Procesamiento en paralelo permite mejor rendimiento
42. 42
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Técnicas de Pintado
Tearing Page Flipping
43. 43
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Técnicas de Pintado
• Page Flipping
• Cache
• Punteros a VRAM | Gráficos -> { Buffer {1..2} } <- Screen
• Swap Buffering
• Mejora el rendimiento
• Eliminación del Tearing (Efecto visual de la imagen desencajada)
45. 45
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Scanlines Vertical ← Video
46. 46
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Scanlines Horizontal ← Video
47. 47
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Java 8 – Emulador Gameboy DMG 01 | Scanlines Mixes ← Video
48. 48
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Mascara
• Display Front nuevo
• Mayor cómputo de renderizado
• Rompe arquitectura LCD { BG & OBJ } Display de la GameBoy
Java 8 – Emulador Gameboy DMG 01 | Técnica Scanlines
49. 49
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• GPU
• Mejor balanceo y rendimiento
• Manejo de shaders
• JOCL OpenCL
• Difícil manejo e interoperabilidad con C99 a través de Java
• Necesidad de varias dependencias
• Rootbeer GPU Compiler
• Java GPU Programming
• CUDA
• Necesidad de varias dependencias
Java 8 – Emulador Gameboy DMG 01 | Técnica Scanlines
57. 57
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Kotlin - IDE’s
Eclipse IntelliJ IDEA Ultimate Android Studio
58. 58
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Kotlin - Construcción de proyectos
Apache Ant Maven Gradle
59. 59
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Fiber (co-operative Multitasking)
• Ejecución Lightweight
• Stackless (no tiene stack propio, proceso corto y eficiente)
• Abstracción de alto nivel de usuario
• No vincula recursos nativos a la JVM (Mínimo)
• Suspensión de funciones
- suspen fun foo = { ... }
• Coste despreciable de invocación
Kotlin - Coroutine
60. 60
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Kotlin - Coroutine | Project Structure
61. 61
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
Kotlin - Coroutine | Project Structure
62. 62
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
fun main(args: Array<String>) {
launch(CommonPool) {
delay(1000L) // Non-blocking
println("World!")
}
println("Hello,")
Thread.sleep(2000L) //Block main thread
}
Result : Hello,
world!
Kotlin - Coroutine
Basic
fun main(args: Array<String>) = runBlocking<Unit> {
launch(CommonPool) {
delay(1000L) // Non-blocking
println("World!")
}
println("Hello,")
delay(2000L) // Non-blocking
}
Result : Hello,
world!
RunBlocking
63. 63
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
fun main(a:Array<String>) = runBlocking<Unit> {
val job = launch(CommonPool) { doWorld() }
println("Hello,")
job.join()
}
suspend fun doWorld() {
delay(1000L)
println("World!")
}
Result : Hello,
world!
Kotlin - Coroutine
w/ suspend
fun main(args: Array<String>) = runBlocking<Unit> {
val jobs = List(100000) {
async(CommonPool) {
delay(500L)
print("*")
}
}
jobs.forEach { it.await() }
}
Result : **** ...
Con Thread`s : out-of-memory… (OEME)
Light-weight
88. 88
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Package { Control.Concurrent.Async 2.1.0 }
• Spawing con automatic cancellation
• Querying Async
• STM operations
• Waiting for multiple Async
• Linking
Haskell
89. 89
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
import Control.Concurrent.Async
…
main = defaultMain tests
tests = [ testCase "asyncWait" asyncWait ]
value = 42 :: Int
data TestException = TestException deriving (Eq,Show,Typeable)
instance Exception TestException
asyncWait :: Assertion
asyncWait = do
a <- async (return value)
r <- wait a
assertEqual "async_wait" r value
Haskell
92. 92
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
open System
let userTimerWithCallback =
let event = new System.Threading.AutoResetEvent(false)
let timer = new System.Timers.Timer(2000.0)
timer.Elapsed.Add (fun _ -> event.Set() | > ignore )
printfn "Esperando : %O" DateTime.Now.TimeOfDay
timer.Start()
printfn "Haciendo cosas mientras esperamos al evento"
event.WaitOne() | > ignore
printfn "Timer ticked %O" DateTime.Now.TimeOfDay
F# - AutoResetEvent
93. 93
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
let fileWriteWithAsync =
use stream = new System.IO.FileStream("test.txt", System.IO.FileMode.Create)
printfn "Empezando escritura asincrona"
let asyncResult = stream.BeginWrite(Array.empty,0,0,null,null)
let async = Async.AwaitIAsyncResult(asyncResult) |> Async.Ignore
printfn "Haciendo cosas mientras esperamos al evento"
Async.RunSynchronously async
printfn "Escritura asíncrona completada"
…
let sleepWorkflow = async{
printfn "Empezamos a dormir el workflow %O" DateTime.Now.TimeOfDay
do! Async.Sleep 2000
printfn "workflow finalizado %O" DateTime.Now.TimeOfDay
}
Async.RunSynchronously sleepWorkflow
F# - IAsyncResult
94. 94
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
let sleepWorkflowMs ms = async {
printfn "%i ms workflow started" ms
do! Async.Sleep ms
printfn "%i ms workflow finished" ms
}
let sleep1 = sleepWorkflowMs 1000
let sleep2 = sleepWorkflowMs 2000
#time
[sleep1; sleep2]
|> Async.Parallel
|> Async.RunSynchronously
#time
F# - IAsyncResult
96. 96
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Explotar rendimiento de procesador/es
• Evitar cuellos de botella, bloqueos...
• Procesamiento de tareas en paralelo
• Trabajar con subprocesos en interfaces de usuario
• Soporte a sistemas de alta escabilidad
• Robustez en las aplicaciones/juegos desarrollados
Conclusiones - OOP
97. 97
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Código desarrollado
- Entendimiento
- Acoplamiento
- Mantenibilidad
- Dificultad de debuggear
Conclusiones - OOP
98. 98
Paradigma FP y OOP usando técnicas avanzadas de programación asíncronas
• Minimización del código
• Basado en expresiones
• Cálculos lambda
• Recursión
• Eficiencia
Conclusiones - FP