Coroutines allow writing asynchronous code in a sequential manner by suspending execution until an asynchronous operation completes. The document discusses how coroutines can be used to simplify asynchronous code for an order processing use case that involves retrieving user, address, product, and store data from repositories. It shows how coroutines eliminate nested subscriptions by suspending until asynchronous operations like retrieving a user or address complete before continuing execution sequentially. The Kotlin compiler converts coroutine code into recursive functions implementing a finite state machine to simulate sequential execution across asynchronous operations.
※다운로드하시면 더 선명한 자료를 보실 수 있습니다.
동접 200만 명이 접속할 수백 대의 게임 서버가 최소한의 MySQL 서버만으로 서비스할 수 있는 구조를 설명합니다.
고성능/고효율의 MySQL 스케일링 기법을 공유합니다. 대규모 게임 서비스에서 이미 검증된 것은 안 비밀~
목차
1. 기본적인 아기텍처
2. ProxySQL을 이용한 더 나은 아키텍처
3. 최종 아키텍처
대상
- 대규모 게임 서비스에 MySQL을 사용한 경험에 관심 있는 분
- ProxySQL에 관심이 있는 서버 개발자 혹은 DBA
- 게임 서버 개발 과정에서 DB 쪽을 유연하게 구성하고 싶은 분
■관련 동영상: https://youtu.be/8Eb_n7JA1yA
Microservices with Java, Spring Boot and Spring CloudEberhard Wolff
Spring Boot makes creating small Java application easy - and also facilitates operations and deployment. But for Microservices need more: Because Microservices are a distributed systems issues like Service Discovery or Load Balancing must be solved. Spring Cloud adds those capabilities to Spring Boot using e.g. the Netflix stack. This talks covers Spring Boot and Spring Cloud and shows how these technologies can be used to create a complete Microservices environment.
자프링(자바 + 스프링) 외길 12년차 서버 개발자가 코프링(코틀린 + 스프링)을 만난 후 코틀린의 특징과 스프링의 코틀린 지원을 알아가며 코프링 월드에서 살아남은 이야기…
코드 저장소: https://github.com/arawn/kotlin-support-in-spring
마이크로서비스 스타일로 만들어진 시스템을 모노리틱 스타일로 이관한 사례와 함께 스프링을 이용해 모듈형 모노리스(modular monoliths)를 만든 경험을 바탕으로 모노리틱/마이크로서비스 보다 본질적인 문제를 제기하고, 문제 해결을 위한 생각을 공유합니다.
https://github.com/arawn/building-modular-monoliths-using-spring
CQRS and Event Sourcing in a Symfony applicationSamuel ROZE
The document discusses using CQRS and event sourcing in a Symfony application. It covers building the domain model to use events, storing events in a repository, using a message bus for commands and events, and creating projections from events for querying. Event handlers can trigger new commands, and projections rebuild data from events for fast reads. The approach allows an application to handle commands asynchronously through decoupled services while maintaining an immutable record of events for audit purposes.
SQLcl overview - A new Command Line Interface for Oracle DatabaseJeff Smith
From the makers of Oracle SQL Developer, we present you a new take on SQL*Plus. A command line interface with a SQL history, table name completion, new commands like CTAS, DDL, Info, and simple things like editing your statement buffers using your keyboard up and down arrow keys!
Spring I/O 2012: Natural Templating in Spring MVC with ThymeleafThymeleaf
Introduction to the Thymeleaf java XML/XHTML/HTML5 template engine by José Miguel Samper and Daniel Fernández at Spring I/O 2012 Madrid, Feb 17th 2012.
※다운로드하시면 더 선명한 자료를 보실 수 있습니다.
동접 200만 명이 접속할 수백 대의 게임 서버가 최소한의 MySQL 서버만으로 서비스할 수 있는 구조를 설명합니다.
고성능/고효율의 MySQL 스케일링 기법을 공유합니다. 대규모 게임 서비스에서 이미 검증된 것은 안 비밀~
목차
1. 기본적인 아기텍처
2. ProxySQL을 이용한 더 나은 아키텍처
3. 최종 아키텍처
대상
- 대규모 게임 서비스에 MySQL을 사용한 경험에 관심 있는 분
- ProxySQL에 관심이 있는 서버 개발자 혹은 DBA
- 게임 서버 개발 과정에서 DB 쪽을 유연하게 구성하고 싶은 분
■관련 동영상: https://youtu.be/8Eb_n7JA1yA
Microservices with Java, Spring Boot and Spring CloudEberhard Wolff
Spring Boot makes creating small Java application easy - and also facilitates operations and deployment. But for Microservices need more: Because Microservices are a distributed systems issues like Service Discovery or Load Balancing must be solved. Spring Cloud adds those capabilities to Spring Boot using e.g. the Netflix stack. This talks covers Spring Boot and Spring Cloud and shows how these technologies can be used to create a complete Microservices environment.
자프링(자바 + 스프링) 외길 12년차 서버 개발자가 코프링(코틀린 + 스프링)을 만난 후 코틀린의 특징과 스프링의 코틀린 지원을 알아가며 코프링 월드에서 살아남은 이야기…
코드 저장소: https://github.com/arawn/kotlin-support-in-spring
마이크로서비스 스타일로 만들어진 시스템을 모노리틱 스타일로 이관한 사례와 함께 스프링을 이용해 모듈형 모노리스(modular monoliths)를 만든 경험을 바탕으로 모노리틱/마이크로서비스 보다 본질적인 문제를 제기하고, 문제 해결을 위한 생각을 공유합니다.
https://github.com/arawn/building-modular-monoliths-using-spring
CQRS and Event Sourcing in a Symfony applicationSamuel ROZE
The document discusses using CQRS and event sourcing in a Symfony application. It covers building the domain model to use events, storing events in a repository, using a message bus for commands and events, and creating projections from events for querying. Event handlers can trigger new commands, and projections rebuild data from events for fast reads. The approach allows an application to handle commands asynchronously through decoupled services while maintaining an immutable record of events for audit purposes.
SQLcl overview - A new Command Line Interface for Oracle DatabaseJeff Smith
From the makers of Oracle SQL Developer, we present you a new take on SQL*Plus. A command line interface with a SQL history, table name completion, new commands like CTAS, DDL, Info, and simple things like editing your statement buffers using your keyboard up and down arrow keys!
Spring I/O 2012: Natural Templating in Spring MVC with ThymeleafThymeleaf
Introduction to the Thymeleaf java XML/XHTML/HTML5 template engine by José Miguel Samper and Daniel Fernández at Spring I/O 2012 Madrid, Feb 17th 2012.
This document provides an overview of the WebLogic Scripting Tool (WLST) and discusses:
- WLST can be used offline to create and modify domains or online to manage running domains.
- Offline mode uses the configuration framework to modify domain templates and configs. Online mode uses JMX to interact with managed beans.
- Common tasks include deploying applications, starting/stopping servers, and browsing or editing configuration settings and runtime data.
- Customizations like adding custom commands or supporting custom managed beans are also discussed.
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
This document discusses using caching to improve performance for web applications. It provides three key points:
1. Cache stores data to serve future requests faster by avoiding accessing the database. It is commonly used for things like login information, page content, and API responses.
2. There are different cache architectures like memcached and Redis that support storing data in-memory for fast retrieval. Factors like data size, update frequency, and consistency requirements determine the appropriate caching strategy.
3. Real-world examples show how companies like Facebook, Twitter, and Wonga use caching extensively to handle high volumes of traffic and database requests. Caching is critical to scaling applications in a cost-effective way.
This document provides an overview of a minimalist framework called Nuxt.js for creating universal server-side rendered (SSR) applications using Vue.js. Some key points covered include:
- Nuxt.js allows developers to write Vue components and pages while abstracting away concerns of client-server code splitting and routing.
- Features include automatic code splitting, SSR, routing, static file serving, bundling/minifying, and error handling.
- The framework uses a pages/ directory to define routes and components and includes Vuex and Vue-Router functionality out of the box.
- Async data loading, custom layouts, global meta tags, and asset handling are also
This document discusses Spring Boot, an open source framework for building microservices and web applications. It provides scaffolding to help build Spring-based services more quickly. The author chose Spring Boot for a project because it integrates well with other frameworks like Jersey and allows building services quickly. Key Spring Boot components discussed include REST frameworks, embedded servers, logging frameworks, security, and metrics. The author outlines their Spring Boot stack and package structure. They discuss using Spring Data for persistence, Swagger for API documentation, and helper libraries like Lombok. The document also covers testing approaches using REST Assured and Spring Integration.
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개if kakao
황민호(robin.hwang) / kakao corp. DSP개발파트
---
최근 Spring Cloud와 Netflix OSS로 MSA를 구성하는 시스템 기반의 서비스들이 많아지는 추세입니다.
카카오에서도 작년에 오픈한 광고 플랫폼 모먼트에 Spring Cloud 기반의 MSA환경을 구성하여, API Gateway도 적용하였는데 1년 반 정도 운영한 경험을 공유할 예정입니다. 더불어 MSA 환경에서는 API Gateway를 통해 인증을 어떻게 처리하는지 알아보고 OAuth2 기반의 JWT Token을 이용한 인증에 대한 이야기도 함께 나눌 예정입니다.
ReactJS for Beginners provides an overview of ReactJS including what it is, advantages, disadvantages, typical setup tools, and examples of basic React code. Key points covered include:
- ReactJS is a JavaScript library for building user interfaces and is component-based.
- Advantages include high efficiency, easier JavaScript via JSX, good developer tools and SEO, and easy testing.
- Disadvantages include React only handling the view layer and requiring other libraries for full MVC functionality.
- Examples demonstrate basic components, properties, events, conditional rendering, and lists in ReactJS.
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Mydbops
MySQL Clustering over InnoDB engines has grown a lot over the last decade. Galera began working with InnoDB early and then Group Replication came to the environment later, where the features are now rich and robust. This presentation offers a technical comparison of both of them.
State management in react applications (Statecharts)Tomáš Drenčák
This document discusses state management in React applications and introduces statecharts as an alternative approach. It covers the limitations of approaches like Flux and Redux, such as global action handling registries and initialization/cleanup issues. Statecharts provide hierarchical and parallel states that can help solve these problems. The document demonstrates how statecharts can be used to structure stores, handle actions polymorphically, and implement common patterns like pages and lists in a more organized way.
This document summarizes a developer who enjoys working in different countries while residing in Australia. They have been fascinated by Spring Framework for a long time and likes to study and apply the latest Spring technologies, including reactive functional programming, to various fields such as blockchain core development. They have written a book called "Toby's Spring" and host a coding broadcast called "Toby's Spring TV" on YouTube.
This document discusses JavaScript module patterns, which help organize and limit the scope of code in projects. It covers different patterns for creating objects and modules, including using constructors, prototypes, the revealing module pattern, CommonJS, and AMD. The basic module pattern allows defining private and public members to encapsulate data and functions. Later patterns like CommonJS and AMD build on this to support asynchronous loading and use in different environments like the browser and Node.js.
The document discusses using JSON in MySQL. It begins by introducing the speaker and outlining topics to be covered, including why JSON is useful, loading JSON data into MySQL, performance considerations when querying JSON data, using generated columns with JSON, and searching multi-valued attributes in JSON. The document then dives into examples demonstrating loading sample data from XML to JSON in MySQL, issues that can arise, and techniques for optimizing JSON queries using generated columns and indexes.
배민찬(https://www.baeminchan.com) 서비스의 백엔드 시스템 중 일부가 지난 1년간 어떤 고민과 아이디어, 결과물을 만들어냈는지 공유하려고 합니다. 발표 중 언급되는 용어나 도구에 대해 일반적인 정의나 간단한 설명은 언급되나 자세히 다루지 않습니다. 사용된 도구들로 어떻게 이벤트 기반 분산 시스템을 만들었는지에 대한 이야기가 중심입니다.
※다운로드하시면 더 선명한 자료를 보실 수 있습니다.
PAYCO 쇼핑의 아키텍처를 MSA로 변경하면서 겪은 삽질을 공유합니다.
레거시 서비스에서 서비스를 분리해내는 방법과 순서, 이후 고려해야 할 사항을 공유하고자 합니다.
목차
1. PAYCO 쇼핑?
2. 프로젝트 진행 과정
3. 아키텍처 공유
대상
- MSA, Spring cloud, Docker, Ansible 등을 실무에 적용하는 방법에 관심이 있는 분
- Spring Cloud를 써서 MSA로 개발하고 싶은데 어디서부터 손대야 할지 모르는 분
■관련 동영상: https://youtu.be/l195D5WT_tE
The document describes the key tables and stages involved in the Oracle order to cash (O2C) cycle. It includes:
1) Order entry which records the order header and lines in OE_ORDER_HEADERS_ALL and OE_ORDER_LINES_ALL tables.
2) Order booking which updates the order status to 'BOOKED' and lines to 'AWAITING_SHIPPING', and populates the WSH_DELIVERY_DETAILS table.
3) Pick release which allocates inventory and updates the order and delivery status in preparation for shipping.
Pig and Java MapReduce are compared for analyzing customer product data stored in Hadoop. Pig Latin is found to be more readable and maintainable due to its SQL-like syntax and limited predefined functions. However, Java MapReduce may have better performance and tooling support from IDEs. The document shows Pig and Java code to calculate top products, average views/purchases, and average purchase amount for each customer group. The Java code uses custom DTOs and is more complex overall.
This document provides an overview of the WebLogic Scripting Tool (WLST) and discusses:
- WLST can be used offline to create and modify domains or online to manage running domains.
- Offline mode uses the configuration framework to modify domain templates and configs. Online mode uses JMX to interact with managed beans.
- Common tasks include deploying applications, starting/stopping servers, and browsing or editing configuration settings and runtime data.
- Customizations like adding custom commands or supporting custom managed beans are also discussed.
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
This document discusses using caching to improve performance for web applications. It provides three key points:
1. Cache stores data to serve future requests faster by avoiding accessing the database. It is commonly used for things like login information, page content, and API responses.
2. There are different cache architectures like memcached and Redis that support storing data in-memory for fast retrieval. Factors like data size, update frequency, and consistency requirements determine the appropriate caching strategy.
3. Real-world examples show how companies like Facebook, Twitter, and Wonga use caching extensively to handle high volumes of traffic and database requests. Caching is critical to scaling applications in a cost-effective way.
This document provides an overview of a minimalist framework called Nuxt.js for creating universal server-side rendered (SSR) applications using Vue.js. Some key points covered include:
- Nuxt.js allows developers to write Vue components and pages while abstracting away concerns of client-server code splitting and routing.
- Features include automatic code splitting, SSR, routing, static file serving, bundling/minifying, and error handling.
- The framework uses a pages/ directory to define routes and components and includes Vuex and Vue-Router functionality out of the box.
- Async data loading, custom layouts, global meta tags, and asset handling are also
This document discusses Spring Boot, an open source framework for building microservices and web applications. It provides scaffolding to help build Spring-based services more quickly. The author chose Spring Boot for a project because it integrates well with other frameworks like Jersey and allows building services quickly. Key Spring Boot components discussed include REST frameworks, embedded servers, logging frameworks, security, and metrics. The author outlines their Spring Boot stack and package structure. They discuss using Spring Data for persistence, Swagger for API documentation, and helper libraries like Lombok. The document also covers testing approaches using REST Assured and Spring Integration.
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개if kakao
황민호(robin.hwang) / kakao corp. DSP개발파트
---
최근 Spring Cloud와 Netflix OSS로 MSA를 구성하는 시스템 기반의 서비스들이 많아지는 추세입니다.
카카오에서도 작년에 오픈한 광고 플랫폼 모먼트에 Spring Cloud 기반의 MSA환경을 구성하여, API Gateway도 적용하였는데 1년 반 정도 운영한 경험을 공유할 예정입니다. 더불어 MSA 환경에서는 API Gateway를 통해 인증을 어떻게 처리하는지 알아보고 OAuth2 기반의 JWT Token을 이용한 인증에 대한 이야기도 함께 나눌 예정입니다.
ReactJS for Beginners provides an overview of ReactJS including what it is, advantages, disadvantages, typical setup tools, and examples of basic React code. Key points covered include:
- ReactJS is a JavaScript library for building user interfaces and is component-based.
- Advantages include high efficiency, easier JavaScript via JSX, good developer tools and SEO, and easy testing.
- Disadvantages include React only handling the view layer and requiring other libraries for full MVC functionality.
- Examples demonstrate basic components, properties, events, conditional rendering, and lists in ReactJS.
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Mydbops
MySQL Clustering over InnoDB engines has grown a lot over the last decade. Galera began working with InnoDB early and then Group Replication came to the environment later, where the features are now rich and robust. This presentation offers a technical comparison of both of them.
State management in react applications (Statecharts)Tomáš Drenčák
This document discusses state management in React applications and introduces statecharts as an alternative approach. It covers the limitations of approaches like Flux and Redux, such as global action handling registries and initialization/cleanup issues. Statecharts provide hierarchical and parallel states that can help solve these problems. The document demonstrates how statecharts can be used to structure stores, handle actions polymorphically, and implement common patterns like pages and lists in a more organized way.
This document summarizes a developer who enjoys working in different countries while residing in Australia. They have been fascinated by Spring Framework for a long time and likes to study and apply the latest Spring technologies, including reactive functional programming, to various fields such as blockchain core development. They have written a book called "Toby's Spring" and host a coding broadcast called "Toby's Spring TV" on YouTube.
This document discusses JavaScript module patterns, which help organize and limit the scope of code in projects. It covers different patterns for creating objects and modules, including using constructors, prototypes, the revealing module pattern, CommonJS, and AMD. The basic module pattern allows defining private and public members to encapsulate data and functions. Later patterns like CommonJS and AMD build on this to support asynchronous loading and use in different environments like the browser and Node.js.
The document discusses using JSON in MySQL. It begins by introducing the speaker and outlining topics to be covered, including why JSON is useful, loading JSON data into MySQL, performance considerations when querying JSON data, using generated columns with JSON, and searching multi-valued attributes in JSON. The document then dives into examples demonstrating loading sample data from XML to JSON in MySQL, issues that can arise, and techniques for optimizing JSON queries using generated columns and indexes.
배민찬(https://www.baeminchan.com) 서비스의 백엔드 시스템 중 일부가 지난 1년간 어떤 고민과 아이디어, 결과물을 만들어냈는지 공유하려고 합니다. 발표 중 언급되는 용어나 도구에 대해 일반적인 정의나 간단한 설명은 언급되나 자세히 다루지 않습니다. 사용된 도구들로 어떻게 이벤트 기반 분산 시스템을 만들었는지에 대한 이야기가 중심입니다.
※다운로드하시면 더 선명한 자료를 보실 수 있습니다.
PAYCO 쇼핑의 아키텍처를 MSA로 변경하면서 겪은 삽질을 공유합니다.
레거시 서비스에서 서비스를 분리해내는 방법과 순서, 이후 고려해야 할 사항을 공유하고자 합니다.
목차
1. PAYCO 쇼핑?
2. 프로젝트 진행 과정
3. 아키텍처 공유
대상
- MSA, Spring cloud, Docker, Ansible 등을 실무에 적용하는 방법에 관심이 있는 분
- Spring Cloud를 써서 MSA로 개발하고 싶은데 어디서부터 손대야 할지 모르는 분
■관련 동영상: https://youtu.be/l195D5WT_tE
The document describes the key tables and stages involved in the Oracle order to cash (O2C) cycle. It includes:
1) Order entry which records the order header and lines in OE_ORDER_HEADERS_ALL and OE_ORDER_LINES_ALL tables.
2) Order booking which updates the order status to 'BOOKED' and lines to 'AWAITING_SHIPPING', and populates the WSH_DELIVERY_DETAILS table.
3) Pick release which allocates inventory and updates the order and delivery status in preparation for shipping.
Pig and Java MapReduce are compared for analyzing customer product data stored in Hadoop. Pig Latin is found to be more readable and maintainable due to its SQL-like syntax and limited predefined functions. However, Java MapReduce may have better performance and tooling support from IDEs. The document shows Pig and Java code to calculate top products, average views/purchases, and average purchase amount for each customer group. The Java code uses custom DTOs and is more complex overall.
The document outlines the key steps and affected tables in the Oracle Apps Order to Cash (O2C) cycle, including:
1. Creating a customer, item, and on-hand inventory for the item. The main tables affected are HZ_CUST_ACCOUNTS, MTL_SYSTEM_ITEMS_B, and MTL_ONHAND_QUANTITIES_DETAIL.
2. Creating a sales order which affects tables like OE_ORDER_HEADERS_ALL and OE_ORDER_LINES_ALL.
3. Releasing the order for picking by updating tables like WSH_DELIVERY_DETAILS and WSH_NEW_DELIVERIES.
The document discusses object-oriented programming and design principles. It defines OOP as a programming paradigm based on classes and cooperating objects. It then discusses the SOLID principles of object-oriented design, which are guidelines for writing reusable, flexible and maintainable code. Specifically, it emphasizes that classes and methods should have a single responsibility, code should be open for extension but closed for modification, and software should be designed to be easy to test, change and add new features to.
In this talk we are going tο… talk about what unit testing is, how you can apply it to ensure your code works as expected and how TDD can help you write new and refactor existing code. Also about how to decide what to test and how you can test real world iOS apps. Finally, we will go through a few tips and tricks that made unit testing in Swift and Xcode 'click' for me and can hopefully help you too.
This document discusses best practices for building RESTful APIs. It defines REST as relying on a stateless, client-server architecture using HTTP. It recommends using URL paths and HTTP methods like GET, POST, PUT, DELETE to describe APIs and provide examples. General rules are outlined for handling collections of resources vs individual resources. Spring REST controllers are demonstrated. Documentation of REST APIs using Swagger is also covered, including annotations for describing endpoints, operations, and responses.
Rhino Mocks is a .NET mocking framework that allows developers to easily create and setup mock objects to test interactions using unit tests. It generates both mocks, which allow expectations to be set and verified, and stubs, which simply return preset values without verification. The document provides examples of using Rhino Mocks to generate mocks and stubs of interfaces, set expectations on mocks, and verify mock interactions using the AAA (Arrange, Act, Assert) syntax. It also distinguishes between mocks and stubs.
MET CS 669 Database Design and Implementation for BusinessLab .docxbuffydtesurina
MET CS 669 Database Design and Implementation for Business
Lab 5: Subqueries
Overview of the Lab
In this lab we learn to work with subqueries, which significantly extend the expressional power of queries. Through the use of subqueries, a single query can extract result sets that could not be extracted without subqueries. Subqueries enable the query creator to ask the database for many complex structures in a single query. This lab teaches you the mechanics crafting SQL queries that harness the power of subqueries to handle more complex use cases.
From a technical perspective, together, we will learn:
· what correlated and uncorrelated subqueries are and the theory supporting both.
· to use subqueries that return a single value, a list of values, and a table of values.
· to use subqueries that use aggregation.
· to address use cases by using uncorrelated subqueries in the column select list, the where clause, and the from clause.
· to address use cases by using correlated subqueries and an EXIST clause in the WHERE clause.
Lab 5 Explanations Reminder
As a reminder, it is important to read through the Lab 5 Explanation document to successfully complete this lab, available in the assignment inbox alongside this lab. The explanation document illustrates how to correctly execute each SQL construct step-by-step, and explains important theoretical and practical details.
Other Reminders
· The examples in this lab will execute in modern versions of Oracle, Microsoft SQL Server, and PostgreSQL as is.
· The screenshots in this lab display execution of SQL in the default SQL clients supported in the course – Oracle SQL Developer, SQL Server Management Studio, and pgAdmin – but your screenshots may vary somewhat as different version of these clients are released.
· Don’t forget to commit your changes if you work on the lab in different sittings, using the “COMMIT” command, so that you do not lose your work.
Section One – Subqueries
Section Background
In this lab, you will practice crafting subqueries for the schema illustrated below.
This schema’s structure supports basic medical product and currency information for an international medical supplier, including store locations, the products they sell, shipping offerings, the currency each location accepts, as well as conversion factors for converting from U.S. dollars into the accepted currency. Due to the specific and technical nature of the names of medical products, the supplier also keeps a list of alternative names for each product that may help customers identify them. This schema models prices and exchange rates at a specific point in time. While a real-world schema would make provision for changes to prices and exchange rates over time, the tables needed to support this have been intentionally excluded from our schema, because their addition would add unneeded complexity on your journey of learning subqueries, expressions, and value manipulation. The schema has just the right a.
Migrations allow you to define and manage changes to your database schema over time. The document discusses ActiveRecord migrations, which provide a way to iteratively improve the database schema by adding, removing, and changing tables and columns. It also covers generating and rolling back migrations, common migration methods like create_table and add_column, and using migrations to support models and testing.
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...PHP Conference Argentina
This document discusses how to build rich web applications by following REST principles and leveraging HTTP. It outlines the history of SOAP and XML-RPC and their limitations compared to REST. It then discusses how AngularJS embraces REST constraints like statelessness, caching, and hypermedia controls. The document argues that AngularJS simplifies building RESTful applications through features like data binding, iteration, organization, and testability compared to alternatives like jQuery. It also shows how to build RESTful resources and APIs in AngularJS using $resource and discusses implementing other HTTP features like caching, authentication, and content negotiation.
10 PHP Snippets to Increase WooCommerce SalesRodolfo Melogli
URL with snippets: https://businessbloomer.com/woocommerce-sales/
I spoke at WordCamp Prague 2019 about “10 PHP Snippets to Increase WooCommerce Sales” and managed to show some simple coding to increasing your WooCommerce sales.
At the URL previously mentioned you can find all the snippets I talked about - copy them, test them, use them and let me know if your WooCommerce revenue increased!
List of snippets I covered:
1) Pressure
2) Trust signals
3) Scarcity
4) Distraction-free checkout
5) “Try before you buy”
6) Thank you page upsell
7) Bulk discount
8) Product Add-ons
9) “Buy One Get One” (BOGO)
10) Free shipping threshold
URL with snippets: https://businessbloomer.com/woocommerce-sales/
The document describes a proposed RESTful API design for an online retail system. It outlines several main services and their resources, including a Retail service with orders, products, and users; a Geo service to calculate distances; a Warehouse service to manage inventory and fulfill orders; a Dispatcher service to handle shipping quotes and orders; and a Supplier service. It provides examples of requests and responses for common operations like placing an order, obtaining shipping quotes, and reserving and confirming inventory. The document aims to define autonomous, stateless services that communicate over HTTP and use standard media types.
The document discusses issues with testing business logic in Orleans grains that access grain state. Specifically, the business logic code is duplicated across grain methods and calling the logic directly in tests fails because the grain state is null. The solution is to use Orleans' declarative persistence by defining a grain state interface and inheriting from Grain, which allows the state to be initialized for tests.
MBL205 Monetizing Your App on Kindle Fire - AWS re: Invent 2012Amazon Web Services
The Amazon In-App Purchasing API makes it easy for you to offer digital content and subscriptions —such as in-game currency, expansion packs, upgrades, magazine issues and more— for purchase within your apps. Within minutes you can be up and running, ready to give millions of Amazon customers the ability to purchase engaging digital content using their Amazon 1-Click settings. Discover how in-app purchasing can help you monetize your apps on Kindle Fire and learn how to integrate the Amazon In-App Purchasing API into your mobile apps.
This document discusses different approaches to unit testing with mocks using Mockito. It explains that mocks allow isolating dependencies to test units in isolation. It compares directly mocking dependencies with Mockito's mocking features like stubbing, argument matchers, custom argument matchers, argument capture, and verification. Mockito provides cleaner mocking by separating stubbing from verification and supporting flexible argument matching.
MySQL is an open source database server that runs on many platforms. It provides database and user management functionality via command line clients or graphical clients like phpMyAdmin. PHP enables accessing and manipulating MySQL databases from web applications. Sample code is provided for a basic e-commerce site using MySQL to store user, product, and cart data in tables and perform common queries like listing products, viewing carts, and searching. The site is built with main.php handling sessions and routing and includes other files for specific tasks like login, logout, adding to cart, etc. which interact with the database using functions defined in db.php.
“Program to an interface, not an implementation” they[1] say …
But when IMyInterface foo = new IMyInterface() is not valid code … how are you supposed to achieve that ? The answer is Dependency Injection.
In this talk, we’ll talk about Dependency injection, what it is and what it is not. We’ll see how it is a valuable set of practices and patterns that help design maintainable software built on top of the SOLID object-oriented principles.
We’ll see how, when used properly, it delivers many benefits such as extensibility and testability … We’ll also cover some anti-patterns, ways of using Dependency Injection that can lead to code that is painful to understand and maintain
This talk is not about DI/IOC containers per se, but focuses on the core concepts of Dependency Injection. Those concepts are essential to understand how to use those “magic-looking” tools (if they are needed at all …)
This talk is not only for .NET developers. It will contain code examples written in C#, but should be understandable by developers with knowledge in other statically-typed object-oriented languages such as Java, Vb.NET, C++ …
This document summarizes steps for creating a shopping cart in a Rails application. It covers generating a Cart model and LineItem model with relationships, using Rails sessions to associate the cart with each user, adding public and private methods, callbacks and validations, adding a button to add items to the cart, and modifying views and controllers. Testing is done to ensure functionality. Homework includes enhancing the functionality by adding a click handler, session counter, and conditional display.
Migrating One of the Most Popular eCommerce Platforms to MongoDBMongoDB
This document summarizes a presentation about migrating the popular Magento eCommerce platform from using a MySQL database to using MongoDB. It describes how Magento currently stores data in MySQL tables with one table per model. It then shows how the data can be migrated to a simpler, nested schema in MongoDB collections without changing Magento's core functionality. It demonstrates how custom resource models abstract the data access to make Magento continue working as before while using the new MongoDB backend.
Migrating one of the most popular e commerce platforms to mongodbMongoDB
This document summarizes a presentation about migrating the popular Magento eCommerce platform from using a MySQL database to using MongoDB. It describes how Magento currently structures data in MySQL tables and discusses reasons for migrating to MongoDB like increased scalability. It then shows how the data can be structured in MongoDB documents while still maintaining Magento's object-oriented data model. New resource models are created to load and save data using MongoDB instead of MySQL queries. The end goal is to migrate existing Magento data to the new MongoDB schema without changing how Magento functions or losing existing features.
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUpanagenda
Webinar Recording: https://www.panagenda.com/webinars/hcl-notes-und-domino-lizenzkostenreduzierung-in-der-welt-von-dlau/
DLAU und die Lizenzen nach dem CCB- und CCX-Modell sind für viele in der HCL-Community seit letztem Jahr ein heißes Thema. Als Notes- oder Domino-Kunde haben Sie vielleicht mit unerwartet hohen Benutzerzahlen und Lizenzgebühren zu kämpfen. Sie fragen sich vielleicht, wie diese neue Art der Lizenzierung funktioniert und welchen Nutzen sie Ihnen bringt. Vor allem wollen Sie sicherlich Ihr Budget einhalten und Kosten sparen, wo immer möglich. Das verstehen wir und wir möchten Ihnen dabei helfen!
Wir erklären Ihnen, wie Sie häufige Konfigurationsprobleme lösen können, die dazu führen können, dass mehr Benutzer gezählt werden als nötig, und wie Sie überflüssige oder ungenutzte Konten identifizieren und entfernen können, um Geld zu sparen. Es gibt auch einige Ansätze, die zu unnötigen Ausgaben führen können, z. B. wenn ein Personendokument anstelle eines Mail-Ins für geteilte Mailboxen verwendet wird. Wir zeigen Ihnen solche Fälle und deren Lösungen. Und natürlich erklären wir Ihnen das neue Lizenzmodell.
Nehmen Sie an diesem Webinar teil, bei dem HCL-Ambassador Marc Thomas und Gastredner Franz Walder Ihnen diese neue Welt näherbringen. Es vermittelt Ihnen die Tools und das Know-how, um den Überblick zu bewahren. Sie werden in der Lage sein, Ihre Kosten durch eine optimierte Domino-Konfiguration zu reduzieren und auch in Zukunft gering zu halten.
Diese Themen werden behandelt
- Reduzierung der Lizenzkosten durch Auffinden und Beheben von Fehlkonfigurationen und überflüssigen Konten
- Wie funktionieren CCB- und CCX-Lizenzen wirklich?
- Verstehen des DLAU-Tools und wie man es am besten nutzt
- Tipps für häufige Problembereiche, wie z. B. Team-Postfächer, Funktions-/Testbenutzer usw.
- Praxisbeispiele und Best Practices zum sofortigen Umsetzen
Maruthi Prithivirajan, Head of ASEAN & IN Solution Architecture, Neo4j
Get an inside look at the latest Neo4j innovations that enable relationship-driven intelligence at scale. Learn more about the newest cloud integrations and product enhancements that make Neo4j an essential choice for developers building apps with interconnected data and generative AI.
Infrastructure Challenges in Scaling RAG with Custom AI modelsZilliz
Building Retrieval-Augmented Generation (RAG) systems with open-source and custom AI models is a complex task. This talk explores the challenges in productionizing RAG systems, including retrieval performance, response synthesis, and evaluation. We’ll discuss how to leverage open-source models like text embeddings, language models, and custom fine-tuned models to enhance RAG performance. Additionally, we’ll cover how BentoML can help orchestrate and scale these AI components efficiently, ensuring seamless deployment and management of RAG systems in the cloud.
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024Neo4j
Neha Bajwa, Vice President of Product Marketing, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
Building Production Ready Search Pipelines with Spark and MilvusZilliz
Spark is the widely used ETL tool for processing, indexing and ingesting data to serving stack for search. Milvus is the production-ready open-source vector database. In this talk we will show how to use Spark to process unstructured data to extract vector representations, and push the vectors to Milvus vector database for search serving.
GraphRAG for Life Science to increase LLM accuracyTomaz Bratanic
GraphRAG for life science domain, where you retriever information from biomedical knowledge graphs using LLMs to increase the accuracy and performance of generated answers
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...SOFTTECHHUB
The choice of an operating system plays a pivotal role in shaping our computing experience. For decades, Microsoft's Windows has dominated the market, offering a familiar and widely adopted platform for personal and professional use. However, as technological advancements continue to push the boundaries of innovation, alternative operating systems have emerged, challenging the status quo and offering users a fresh perspective on computing.
One such alternative that has garnered significant attention and acclaim is Nitrux Linux 3.5.0, a sleek, powerful, and user-friendly Linux distribution that promises to redefine the way we interact with our devices. With its focus on performance, security, and customization, Nitrux Linux presents a compelling case for those seeking to break free from the constraints of proprietary software and embrace the freedom and flexibility of open-source computing.
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceIndexBug
Imagine a world where machines not only perform tasks but also learn, adapt, and make decisions. This is the promise of Artificial Intelligence (AI), a technology that's not just enhancing our lives but revolutionizing entire industries.
In the rapidly evolving landscape of technologies, XML continues to play a vital role in structuring, storing, and transporting data across diverse systems. The recent advancements in artificial intelligence (AI) present new methodologies for enhancing XML development workflows, introducing efficiency, automation, and intelligent capabilities. This presentation will outline the scope and perspective of utilizing AI in XML development. The potential benefits and the possible pitfalls will be highlighted, providing a balanced view of the subject.
We will explore the capabilities of AI in understanding XML markup languages and autonomously creating structured XML content. Additionally, we will examine the capacity of AI to enrich plain text with appropriate XML markup. Practical examples and methodological guidelines will be provided to elucidate how AI can be effectively prompted to interpret and generate accurate XML markup.
Further emphasis will be placed on the role of AI in developing XSLT, or schemas such as XSD and Schematron. We will address the techniques and strategies adopted to create prompts for generating code, explaining code, or refactoring the code, and the results achieved.
The discussion will extend to how AI can be used to transform XML content. In particular, the focus will be on the use of AI XPath extension functions in XSLT, Schematron, Schematron Quick Fixes, or for XML content refactoring.
The presentation aims to deliver a comprehensive overview of AI usage in XML development, providing attendees with the necessary knowledge to make informed decisions. Whether you’re at the early stages of adopting AI or considering integrating it in advanced XML development, this presentation will cover all levels of expertise.
By highlighting the potential advantages and challenges of integrating AI with XML development tools and languages, the presentation seeks to inspire thoughtful conversation around the future of XML development. We’ll not only delve into the technical aspects of AI-powered XML development but also discuss practical implications and possible future directions.
For the full video of this presentation, please visit: https://www.edge-ai-vision.com/2024/06/building-and-scaling-ai-applications-with-the-nx-ai-manager-a-presentation-from-network-optix/
Robin van Emden, Senior Director of Data Science at Network Optix, presents the “Building and Scaling AI Applications with the Nx AI Manager,” tutorial at the May 2024 Embedded Vision Summit.
In this presentation, van Emden covers the basics of scaling edge AI solutions using the Nx tool kit. He emphasizes the process of developing AI models and deploying them globally. He also showcases the conversion of AI models and the creation of effective edge AI pipelines, with a focus on pre-processing, model conversion, selecting the appropriate inference engine for the target hardware and post-processing.
van Emden shows how Nx can simplify the developer’s life and facilitate a rapid transition from concept to production-ready applications.He provides valuable insights into developing scalable and efficient edge AI solutions, with a strong focus on practical implementation.
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
Removing Uninteresting Bytes in Software FuzzingAftab Hussain
Imagine a world where software fuzzing, the process of mutating bytes in test seeds to uncover hidden and erroneous program behaviors, becomes faster and more effective. A lot depends on the initial seeds, which can significantly dictate the trajectory of a fuzzing campaign, particularly in terms of how long it takes to uncover interesting behaviour in your code. We introduce DIAR, a technique designed to speedup fuzzing campaigns by pinpointing and eliminating those uninteresting bytes in the seeds. Picture this: instead of wasting valuable resources on meaningless mutations in large, bloated seeds, DIAR removes the unnecessary bytes, streamlining the entire process.
In this work, we equipped AFL, a popular fuzzer, with DIAR and examined two critical Linux libraries -- Libxml's xmllint, a tool for parsing xml documents, and Binutil's readelf, an essential debugging and security analysis command-line tool used to display detailed information about ELF (Executable and Linkable Format). Our preliminary results show that AFL+DIAR does not only discover new paths more quickly but also achieves higher coverage overall. This work thus showcases how starting with lean and optimized seeds can lead to faster, more comprehensive fuzzing campaigns -- and DIAR helps you find such seeds.
- These are slides of the talk given at IEEE International Conference on Software Testing Verification and Validation Workshop, ICSTW 2022.
11. - 구매자 조회
- 주소 조회 및 유효성 체크
- 상품 목록 조회
- 스토어 목록 조회
- 주문 생성
01. Coroutine 소개
주문 생성 동기 코드 fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdSync(userId)
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserSync(buyer).last()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsSync(productIds)
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsSync(products)
check(stores.isNotEmpty())
// 5. 주문 생성
val order =
orderRepository.createOrderSync(buyer, products, stores, address)
return order
}
21. - Maybe<T>.awaitSingle
- Publisher<T>.awaitLast
- Flow<T>.toList
- CompletableFuture<T>.await
01. Coroutine 소개
Coroutine suspend fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdAsMaybe(userId).awaitSingle()
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserAsPublisher(buyer).awaitLast()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsAsFlux(productIds).asFlow().toList()
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsAsMulti(products).asFlow().toList()
check(stores.isNotEmpty())
// 5. 주문 생성
val order = orderRepository.createOrderAsFuture(buyer, products, stores, address).await()
return order
}
22. 01. Coroutine 소개
suspend fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdAsMaybe(userId).awaitSingle()
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserAsPublisher(buyer).awaitLast()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsAsFlux(productIds).asFlow().toList()
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsAsMulti(products).asFlow().toList()
check(stores.isNotEmpty())
// 5. 주문 생성
val order = orderRepository.createOrderAsFuture(buyer, products, stores, address).await()
return order
}
fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdSync(userId)
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserSync(buyer).last()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsSync(productIds)
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsSync(products)
check(stores.isNotEmpty())
// 5. 주문 생성
val order = orderRepository.createOrderSync(buyer, products, stores, address)
return order
}
동기코드 그리고 Coroutine
23. 01. Coroutine 소개
Coroutine 실행 @Test
fun `should return a createdOrder in coroutine`() = runBlocking {
// given
val userId = "user1"
val productIds = listOf("product1", "product2", "product3")
// when
val watch = StopWatch().also { it.start() }
val inputValues = CreateOrderCoroutineUseCase.InputValues(userId, productIds)
val createdOrder = createOrderUseCase.execute(inputValues)
watch.stop()
println("Time Elapsed: ${watch.time}ms")
// then
println(createdOrder)
}
- runBlocking은 동기코드에서
coroutine을 실행할 수 있게
bridge 역할
26. - 경량화된 쓰레드?
- 특정 지점에서 정지했다가 재개할 수
있는 쓰레드?
02. Coroutine 톺아보기
Coroutine? suspend fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdAsMaybe(userId).awaitSingle()
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserAsPublisher(buyer).awaitLast()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsAsFlux(productIds).asFlow().toList()
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsAsMulti(products).asFlow().toList()
check(stores.isNotEmpty())
// 5. 주문 생성
val order = orderRepository.createOrderAsFuture(buyer, products, stores, address).await()
return order
}
27. - Finite State Machine 기반의
재귀 함수로 변환
kotlin 컴파일러가 suspend가 붙은 함수에
추가적인 코드를 추가
- Continuation 인자를 타겟 함수에
추가하고 Continuation 구현체를
생성
- 타겟 함수 내의 모든 suspend 함수에
생성한 continuation 객체를 패스
- 코드를 분리해서 switch case 안에
넣고 label을 이용해서 state를 변경
02. Coroutine 톺아보기
Kotlin Compiler
28. - execute 함수가 실행되면 재귀
호출을 이용해서 스스로(execute
함수)를 실행하면서 state를 변경
- state가 최종에 도달하면 값을
caller에 반환
02. Coroutine 톺아보기
FSM 기반의 재귀 함수
재귀호출 재귀호출
재귀호출
재귀호출 complete
30. - SharedData를 통해서 여러 가지
context를 저장
- label은 state machine의 현재 state
값
- 이전 state에서 찾은 값들을 buyer,
address, products, stores, order에
저장
- resumeWith로 재귀 호출을 하고
결과를 result에 저장
- 인자의 sharedData가 null이라면
생성하고 아니면 있는 sharedData를
사용
02. Coroutine 톺아보기
FSM 기반의 동기 코드 class SharedData {
var label: Int = 0
lateinit var result: Any
lateinit var buyer: User
lateinit var address: Address
lateinit var products: List<Product>
lateinit var stores: List<Store>
lateinit var order: Order
lateinit var resumeWith: (result: Any) -> Order
}
fun execute(
inputValues: InputValues,
sharedData: SharedData? = null,
): Order {
val (userId, productIds) = inputValues
val that = this
val shared = sharedData ?: SharedData().apply {
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
}
32. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 0
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
33. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 1
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
34. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 2
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
35. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 3
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
36. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 4
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
37. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; state 5
return when (shared.label) {
0 -> {
shared.label = 1
userRepository.findUserByIdSync(userId)
.let { user ->
shared.resumeWith(user)
}
}
1 -> {
shared.label = 2
shared.buyer = shared.result as User
addressRepository.findAddressByUserSync(shared.buyer).last()
.let { address ->
shared.resumeWith(address)
}
}
2 -> {
shared.label = 3
shared.address = shared.result as Address
checkValidRegion(shared.address)
productRepository.findAllProductsByIdsSync(productIds)
.let { products ->
shared.resumeWith(products)
}
}
3 -> {
shared.label = 4
shared.products = shared.result as List<Product>
check(shared.products.isNotEmpty())
storeRepository.findStoresByProductsSync(shared.products)
.let { stores ->
shared.resumeWith(stores)
}
}
4 -> {
shared.label = 5
shared.stores = shared.result as List<Store>
check(shared.stores.isNotEmpty())
orderRepository.createOrderSync(
shared.buyer, shared.products, shared.stores, shared.address
).let { order ->
shared.resumeWith(order)
}
}
5 -> {
shared.order = shared.result as Order
shared.order
}
else -> throw IllegalAccessException()
}
this.resumeWith = fun (result: Any): Order {
this.result = result
return that.execute(inputValues, this)
}
38. 02. Coroutine 톺아보기
FSM 기반의 동기 코드 ; 실행 @Test
fun `should return a createdOrder in sync with state machine`() {
// given
val userId = "user1"
val productIds = listOf("product1", "product2", "product3")
// when
val watch = StopWatch().also { it.start() }
val inputValues = CreateOrderSyncStateMachineUseCase.InputValues(
userId, productIds)
val createdOrder = createOrderUseCase.execute(inputValues)
watch.stop()
println("Time Elapsed: ${watch.time}ms")
// then
println(createdOrder)
}
- execute를 실행할때, 두번째
인자를 넘기지 않아서 default
value인 null로 제공
40. - SharedDataContinuation를 통해서
여러 가지 context를 저장
- label은 state machine의 현재 state
값
- 이전 state에서 찾은 값들을 buyer,
address, products, stores, order에
저장
- resumeWith로 재귀 호출을 하여
결과를 result에 저장
- 인자의 sharedData가
SharedDataContinuation 타입이
아니라면 생성
02. Coroutine 톺아보기
FSM 기반의 비동기 코드 class SharedDataContinuation( // 실제로 continuation 구현체는 method
안에
val completion: Continuation<Any>,
) : Continuation<Any> {
var label: Int = 0
lateinit var result: Any
lateinit var buyer: User
lateinit var address: Address
lateinit var products: List<Product>
lateinit var stores: List<Store>
lateinit var order: Order
lateinit var resume: () -> Unit
override val context: CoroutineContext = completion.context
override fun resumeWith(result: Result<Any>) {
this.result = result
this.resume()
}
}
fun execute(inputValues: InputValues, completion: Continuation<Any>) {
val (userId, productIds) = inputValues
val that = this
val cont = completion as? SharedDataContinuation
?: SharedDataContinuation(completion).apply {
resume = fun() {
// recursive self
that.execute(inputValues, this)
41. 02. Coroutine 톺아보기
FSM 기반의 비동기 코드 class SharedDataContinuation(
val completion: Continuation<Any>,
) : Continuation<Any> {
var label: Int = 0
lateinit var result: Any
lateinit var buyer: User
lateinit var address: Address
lateinit var products: List<Product>
lateinit var stores: List<Store>
lateinit var order: Order
lateinit var resume: () -> Unit
override val context: CoroutineContext = completion.context
override fun resumeWith(result: Result<Any>) {
this.result = result
this.resume()
}
}
fun execute(inputValues: InputValues, completion: Continuation<Any>) {
val (userId, productIds) = inputValues
val that = this
val cont = completion as? SharedDataContinuation
?: SharedDataContinuation(completion).apply {
resume = fun() {
// recursive self
that.execute(inputValues, this)
}
public interface Continuation<in T> {
/**
* The context of the coroutine that corresponds to this
continuation.
*/
public val context: CoroutineContext
/**
* Resumes the execution of the corresponding coroutine
passing a successful or failed [result] as the
* return value of the last suspension point.
*/
public fun resumeWith(result: Result<T>)
}
42. 02. Coroutine 톺아보기
FSM 기반의 비동기 코드 ; 실행
- testContinuation을 생성해서
execute 함수에 주입
@Test
fun `should return a createdOrder in async with state machine`() {
// given
val userId = "user1"
val productIds = listOf("product1", "product2", "product3")
// when
val watch = StopWatch().also { it.start() }
val lock = CountDownLatch(1)
val testContinuation = object : Continuation<Any> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Any>) {
watch.stop()
lock.countDown()
println("Time Elapsed: ${watch.time}ms")
println(result.getOrThrow())
}
}
val inputValues = CreateOrderAsyncStateMachine3UseCase.InputValues(userId, productIds)
createOrderUseCase.execute(inputValues, testContinuation)
// then
lock.await(3000, TimeUnit.MILLISECONDS)
}
50. 02. Coroutine 톺아보기
FSM 기반의 비동기 코드 ; 최종 class SharedDataContinuation(
val completion: Continuation<Any>,
) : Continuation<Any> {
var label: Int = 0
lateinit var result: Any
lateinit var buyer: User
lateinit var address: Address
lateinit var products: List<Product>
lateinit var stores: List<Store>
lateinit var order: Order
lateinit var resume: () -> Unit
override val context: CoroutineContext = completion.context
override fun resumeWith(result: Result<Any>) {
this.result = result
this.resume()
}
}
fun execute(inputValues: InputValues, completion: Continuation<Any>) {
val (userId, productIds) = inputValues
val that = this
val cont = completion as? SharedDataContinuation
?: SharedDataContinuation(completion).apply {
resume = fun() {
// recursive self
that.execute(inputValues, this)
}
- completion은 외부에서 주입하는
continuation 기반의 객체
51. 02. Coroutine 톺아보기
FSM 기반의 비동기 코드 ; 실행
- testContinuation을 생성해서
execute 함수에 주입
@Test
fun `should return a createdOrder in async with state machine`() {
// given
val userId = "user1"
val productIds = listOf("product1", "product2", "product3")
// when
val watch = StopWatch().also { it.start() }
val lock = CountDownLatch(1)
val testContinuation = object : Continuation<Any> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Any>) {
watch.stop()
lock.countDown()
println("Time Elapsed: ${watch.time}ms")
println(result.getOrThrow())
}
}
val inputValues = CreateOrderAsyncStateMachine3UseCase.InputValues(userId, productIds)
createOrderUseCase.execute(inputValues, testContinuation)
// then
lock.await(3000, TimeUnit.MILLISECONDS)
}
58. 02. Coroutine 톺아보기
FSM 기반의 Coroutines ; continuation 제거
when (cont.label) {
0 -> {
cont.label = 1
val buyer = userRepository.findUserByIdAsMaybe(userId)
.awaitSingle()
}
1 -> {
cont.label = 2
cont.buyer = (cont.result as Result<User>).getOrThrow()
val address = addressRepository.findAddressByUserAsPublisher(buyer)
.awaitLast()
}
2 -> {
cont.label = 3
cont.address = (cont.result as Result<Address>).getOrThrow()
checkValidRegion(address)
val products = productRepository.findAllProductsByIdsAsFlux(productIds)
.toList()
}
3 -> {
cont.label = 4
cont.products = (cont.result as Result<List<Product>>).getOrThrow()
check(products.isNotEmpty())
val stores = storeRepository.findStoresByProductsAsMulti(products)
.toList()
}
4 -> {
cont.label = 5
cont.stores = (cont.result as Result<List<Store>>).getOrThrow()
check(stores.isNotEmpty())
val order = orderRepository.createOrderAsFuture(
buyer, products, stores, address
).awaitSingle()
}
5 -> {
cont.order = (cont.result as Result<Order>).getOrThrow()
cont.completion.resumeWith(Result.success(cont.order))
return order
}
else -> throw IllegalAccessException()
}
59. 02. Coroutine 톺아보기
Coroutines ; 최종 // 0 ->
val buyer = userRepository.findUserByIdAsMaybe(userId).awaitSingle()
// 1 ->
val address = addressRepository.findAddressByUserAsPublisher(buyer)
.awaitLast()
checkValidRegion(address)
// 2 ->
val products = productRepository.findAllProductsByIdsAsFlux(productIds)
.toList()
check(products.isNotEmpty())
// 3 ->
val stores = storeRepository.findStoresByProductsAsMulti(products)
.toList()
check(stores.isNotEmpty())
// 4 ->
val order = orderRepository.createOrderAsFuture(
buyer, products, stores, address
).awaitSingle()
return order
60. 02. Coroutine 톺아보기
Coroutines ; 실행 @Test
fun `should return a createdOrder in coroutine`() = runBlocking {
// given
val userId = "user1"
val productIds = listOf("product1", "product2", "product3")
// when
val watch = StopWatch().also { it.start() }
val inputValues = CreateOrderCoroutineUseCase.InputValues(userId, productIds)
val createdOrder = createOrderUseCase.execute(inputValues)
watch.stop()
println("Time Elapsed: ${watch.time}ms")
// then
println(createdOrder)
}
62. 03. 다음회 예고
Async를 사용한 동시성 처리 suspend fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = userRepository.findUserByIdAsMaybe(userId).awaitSingle()
// 2. 주소 조회 및 유효성 체크
val addressDeferred = CoroutineScope(Dispatchers.IO).async {
addressRepository.findAddressByUserAsPublisher(buyer)
.awaitLast()
}
// 3. 상품들 조회
val products =
productRepository.findAllProductsByIdsAsFlux(productIds).asFlow().toList()
check(products.isNotEmpty())
// 4. 스토어 조회
val storesDeferred = CoroutineScope(Dispatchers.IO).async {
storeRepository.findStoresByProductsAsMulti(products).asFlow().toList()
}
val address = addressDeferred.await()
val stores = storesDeferred.await()
checkValidRegion(address)
check(stores.isNotEmpty())
// 5. 주문 생성
- CoroutineDispatcher
- 여러 Thread를 오고가며 로직을
처리 가능
63. 03. 다음회 예고
try/catch를 이용한 에러 핸들링 suspend fun execute(inputValues: InputValues): Order {
val (userId, productIds) = inputValues
// 1. 구매자 조회
val buyer = try {
userRepository.findUserByIdAsMaybe(userId).awaitSingle()
} catch (e: Exception) {
throw NoSuchElementException("no such user")
}
// 2. 주소 조회 및 유효성 체크
val address = addressRepository.findAddressByUserAsPublisher(buyer)
.awaitLast()
checkValidRegion(address)
// 3. 상품들 조회
val products = productRepository.findAllProductsByIdsAsFlux(productIds).asFlow().toList()
check(products.isNotEmpty())
// 4. 스토어 조회
val stores = storeRepository.findStoresByProductsAsMulti(products).asFlow().toList()
check(stores.isNotEmpty())
// 5. 주문 생성
val order = orderRepository.createOrderAsFuture(buyer, products, stores, address).await()
return order
}
- try/catch를 통해서 일관성 있게
에러 핸들링 가능
64. 03. 다음회 예고
그 외에
- Structured concurrency
- Channel
- Flow