Skip to content

Latest commit

 

History

History
205 lines (142 loc) · 6.41 KB

17장 타임라인 조율하기.md

File metadata and controls

205 lines (142 loc) · 6.41 KB

17장 타임라인 조율하기

좋은 타임라인 원칙

  1. 타임라인은 적을 수록 이해하기 쉽다.
  2. 타임라인은 짧을 수록 이해하기 쉽다.
  3. 공유하는 자원이 적을수록 이해하기 쉽다.
  4. 자원을 공유한다면 서로 조율해야한다. 5. 시간을 일급으로 다룬다.
  • 액션의 순서와 타이밍을 맞추는것은 어렵기때문에, 타임라인을 관리하는 재사용가능한 객체를 만들어 해결할수 있다. 호출 순서와 반복은 직접 다룰수있다.
  • 모든 언어에는 암묵적인 모델 존재 -> 하지만 우리가 해결하려는 문제와 맞지 않기 때문에 함수형 프로그래밍으로 문제를 해결할 시간 모델 생성

예제

장바구니 큐 동작의 최적화 진행이후, 버그 발생

function add_item_to_cart(item) {
	cart = add_item(cart, item);
	update_total_queue(cart);
}

function calc_cart_total(cart, callback) {
	var total = 0;
	cost_ajax(cart, function(cost) {
		total += cost;

//    최적화 이전
//		shipping_ajax(cart, function(shipping) {
//			total += shipping;
//			callback(total);
//		});	
	});
//    최적화 이후
	shipping_ajax(cart, function(shipping) {
		total += shipping;
		callback(total);
	});
}

function calc_cart_worker(cart, done) {
	calc_cart_total(cart, function(total) {
		update_total_dom(total);
		done(total);
	});
}

var update_total_queue = DroppingQueue(1, calc_cart_worker);
  1. 액션을 확인하기

  1. 액션 그리기

  1. 다이어그램 단순화 하기

  1. 실행 가능 순서 분석

문제 해결 -> 모든 병렬 콜백 기다리기

  • 두 응답이후, DOM이 업데이트 되도록 수정

  • 여러 타임라인이 끝나는 지점은 “Cut”으로 분리
    • Cut은 순서를 보장해주는 역할
    • Cut 아래단계 실행전, 윗 단계가 끝나야됨
    • Cut을 통해 복잡한 타임라인을 분리하여, 분석할수 있다.

타임라인을 나누기 위한 동시성 기본형

  • 단일 스레드 환경인 자바스크립트에서만 동작하는 Cut
function Cut(num, callback) {
	var num_finished = 0;
	return function() {
		num_finished += 1;
		if(num_finished === num)
		callback();
	};
}


var done = Cut(3, function() {
	console.log("3 timelines are finished");
});

done();
done();
done();

// console=> "3 timelines are finished"
  • 문제 해결 코드 적용
function calc_cart_total(cart, callback) {
	var total = 0;
	var done = Cut(2, function() {
		callback(total);
	});
	cost_ajax(cart, function(cost) {
		total += cost;
		done();
	});
	shipping_ajax(cart, function(shipping) {
		total += shipping;
		done();
	});
}
  1. 비동기 웹 요청
  2. 결과를 합쳐야 하는 두개의 api응답
  3. 예측 불가능한 사용자의 액션

딱 한번만 호출하는 기본형

function JustOnce(action) {
	var alreadyCalled = false;
	return function(a, b, c) {
		if(alreadyCalled) return;
		alreadyCalled = true;
		return action(a, b, c);
	};
}
  • 마찬가지로 멀티쓰레드 환경에서는 주의 해야함
  • 타임라인이 액션을 공유하고 협력하는 방법

암묵적 시간 모델 VS 명시적 시간 모델

  • 모든 언어는 암묵적으로 시간에 대한 모델 보유
    • 순서와 반복

JavaScript의 시간 모델

  1. 순차적 구문, 순차적 실행
  2. 두 타임라인의 단계는 왼쪽 or 오른쪽 이 먼저 실행됨
  3. 비동기 이벤트는 새로운 타임라인
  4. 액션은 호출할때마다 실행

함수형 개발자는 요구사항에 맞는 실행 방식에 가까운 시간 모델을 만든다

  • 비동기콜백의 경우, 여러 타임라인을 방지하고자, 큐를 생성
  • 여러번 호출되어도 한번만 호출되는 액션 -> 즉 함수형 개발자는 시간 모델을 다룬다

요약 : 타임라인 사용하기

  • 타임라인 수를 줄입니다
    • 스레드나 비동기 호출, 서버 요청을 줄여 적은 타임라인을 만들면 시스템이 단순해딘다.
  • 타임라인 길이를 줄이자
    • 타임라인에 있는 액션을 줄이고, 액션을 계산으로 바꾸자
  • 공유 자원을 없애자
    • 자원을 공유하지 않는 타임라인은 순서 문제가 생기지 않는다. 가능한 단일 스레드에서 공유자원에서 접근하자
  • 동시성 기본형으로 자원을 공유한다
    • 큐나 락을 사용해서 안전하게 공유할 수 있는 방법을 사용하자
  • 동시성 기본형으로 조율하자
    • 타임라인을 조율하기 위해, Promise나 컷과 같은 것으로 액션에 순서나 반복을 제한하자

  • 두 타임라인이 협력할수 있는 동시성 기본형을 사용하여, 타임라인을 조율
  • 언어가 제공하는 암묵적 시간모델 대신 새로운 시간 모델을 만들어 사용
  • 타임라인을 조율하기 위해 동시성 기본형 생성, 가능한 순서를 제한해 올바른 결과가 나오도록 사용
  • 타임라인을 나누는것도 타임라인을 조율하는 방법 중하나, 컷은 모든 타임라인의 작업이 끝날때 까지 기다려, 새로운 타임라인이 시작할수 있도록 도와준다.

질문 및 소감

멜리님 : 개발할 때 타임라인을 제대로 고려하지 않으면, 다양한 문제가 발생할 수 있다는 것을 알게 되었습니다. 저는 cut()이라는 걸 처음 봤는데,이게 혹시 대중적으로 사용되나요?

  • 타임라인의 Cut의 역할을 사용하는 Promise.all , Rx의 zip , 코루틴 등등을 활용

마크님 : Cut 이라는 함수를 통해서 어떤 메세지를 주려고 하는건지는 알겠는데 코드 예시를 semaphore를 사용하는 나쁜 예시처럼 보여서 좀 의미가 퇴색되는 거 같네요…

신기 : 파이썬에서 cut과 같은 기능을 하는건 asyncio.gather 라는게 있습니다.(이름이 달랐던거같은데 지금 찾아보니 이거로나오네요….) https://docs.python.org/ko/3/library/asyncio-task.html#running-tasks-concurrently